lkml.org 
[lkml]   [2000]   [Feb]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] rvmalloc and rvfree

    It was bothering me so much about the discussion we had about rvmalloc I
    made a patch for it. This patch places the code inside vmalloc.c and I
    changed vmalloc.h so drivers can use rvmalloc, rvfree, kvirt_to_bus, and
    kvirt_to_pa. I removed the duplicated code out of bttv.c and the USB
    drivers using it. I don't know if my solution is correct but its a start.
    Modify it at will. It's against 2.3.43-8 and it compiles but I couldn't
    test it. I don't have any drivers that use this code. So please test it as
    well.

    Codito, ergo sum - "I code, therefore I am"
    James Simmons (o_
    fbdev/gfx developer (o_ (o_ //\
    http://www.linux-fbdev.org (/)_ (/)_ V_/_
    http://linuxgfx.sourceforge.net

    diff -urN linux-2.3.43-8/drivers/char/bttv.c linux/drivers/char/bttv.c
    --- linux-2.3.43-8/drivers/char/bttv.c Thu Feb 10 15:07:18 2000
    +++ linux/drivers/char/bttv.c Thu Feb 10 18:32:47 2000
    @@ -99,124 +99,6 @@

    #define BURSTOFFSET 76

    -
    -/*******************************/
    -/* Memory management functions */
    -/*******************************/
    -
    -#define MDEBUG(x) do { } while(0) /* Debug memory management */
    -
    -/* [DaveM] I've recoded most of this so that:
    - * 1) It's easier to tell what is happening
    - * 2) It's more portable, especially for translating things
    - * out of vmalloc mapped areas in the kernel.
    - * 3) Less unnecessary translations happen.
    - *
    - * The code used to assume that the kernel vmalloc mappings
    - * existed in the page tables of every process, this is simply
    - * not guarenteed. We now use pgd_offset_k which is the
    - * defined way to get at the kernel page tables.
    - */
    -
    -/* Given PGD from the address space's page table, return the kernel
    - * virtual mapping of the physical memory mapped at ADR.
    - */
    -static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
    -{
    - unsigned long ret = 0UL;
    - pmd_t *pmd;
    - pte_t *ptep, pte;
    -
    - if (!pgd_none(*pgd)) {
    - pmd = pmd_offset(pgd, adr);
    - if (!pmd_none(*pmd)) {
    - ptep = pte_offset(pmd, adr);
    - pte = *ptep;
    - if(pte_present(pte))
    - ret = (page_address(pte_page(pte))|(adr&(PAGE_SIZE-1)));
    - }
    - }
    - MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static inline unsigned long uvirt_to_bus(unsigned long adr)
    -{
    - unsigned long kva, ret;
    -
    - kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
    - ret = virt_to_bus((void *)kva);
    - MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static inline unsigned long kvirt_to_bus(unsigned long adr)
    -{
    - unsigned long va, kva, ret;
    -
    - va = VMALLOC_VMADDR(adr);
    - kva = uvirt_to_kva(pgd_offset_k(va), va);
    - ret = virt_to_bus((void *)kva);
    - MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -/* Here we want the physical address of the memory.
    - * This is used when initializing the contents of the
    - * area and marking the pages as reserved.
    - */
    -static inline unsigned long kvirt_to_pa(unsigned long adr)
    -{
    - unsigned long va, kva, ret;
    -
    - va = VMALLOC_VMADDR(adr);
    - kva = uvirt_to_kva(pgd_offset_k(va), va);
    - ret = __pa(kva);
    - MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static void * rvmalloc(unsigned long size)
    -{
    - void * mem;
    - unsigned long adr, page;
    -
    - mem=vmalloc(size);
    - if (mem)
    - {
    - memset(mem, 0, size); /* Clear the ram out, no junk to the user */
    - adr=(unsigned long) mem;
    - while (size > 0)
    - {
    - page = kvirt_to_pa(adr);
    - mem_map_reserve(MAP_NR(__va(page)));
    - adr+=PAGE_SIZE;
    - size-=PAGE_SIZE;
    - }
    - }
    - return mem;
    -}
    -
    -static void rvfree(void * mem, unsigned long size)
    -{
    - unsigned long adr, page;
    -
    - if (mem)
    - {
    - adr=(unsigned long) mem;
    - while (size > 0)
    - {
    - page = kvirt_to_pa(adr);
    - mem_map_unreserve(MAP_NR(__va(page)));
    - adr+=PAGE_SIZE;
    - size-=PAGE_SIZE;
    - }
    - vfree(mem);
    - }
    -}
    -
    -
    -
    /*
    * Create the giant waste of buffer space we need for now
    * until we get DMA to user space sorted out (probably 2.3.x)
    diff -urN linux-2.3.43-8/drivers/usb/cpia.c linux/drivers/usb/cpia.c
    --- linux-2.3.43-8/drivers/usb/cpia.c Thu Feb 10 15:07:20 2000
    +++ linux/drivers/usb/cpia.c Thu Feb 10 18:36:08 2000
    @@ -31,122 +31,7 @@
    /* 384 because xawtv tries to grab 384 even though we tell it 352 is our max */
    #define MAX_FRAME_SIZE (384 * 288 * 3)

    -/*******************************/
    -/* Memory management functions */
    -/*******************************/
    -
    -#define MDEBUG(x) do { } while(0) /* Debug memory management */
    -
    static struct usb_driver cpia_driver;
    -
    -/* Given PGD from the address space's page table, return the kernel
    - * virtual mapping of the physical memory mapped at ADR.
    - */
    -static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
    -{
    - unsigned long ret = 0UL;
    - pmd_t *pmd;
    - pte_t *ptep, pte;
    -
    - if (!pgd_none(*pgd)) {
    - pmd = pmd_offset(pgd, adr);
    - if (!pmd_none(*pmd)) {
    - ptep = pte_offset(pmd, adr);
    - pte = *ptep;
    - if (pte_present(pte))
    - ret = page_address(pte_page(pte)) | (adr & (PAGE_SIZE-1));
    - }
    - }
    - MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static inline unsigned long uvirt_to_bus(unsigned long adr)
    -{
    - unsigned long kva, ret;
    -
    - kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
    - ret = virt_to_bus((void *)kva);
    - MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static inline unsigned long kvirt_to_bus(unsigned long adr)
    -{
    - unsigned long va, kva, ret;
    -
    - va = VMALLOC_VMADDR(adr);
    - kva = uvirt_to_kva(pgd_offset_k(va), va);
    - ret = virt_to_bus((void *)kva);
    - MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -/* Here we want the physical address of the memory.
    - * This is used when initializing the contents of the
    - * area and marking the pages as reserved.
    - */
    -static inline unsigned long kvirt_to_pa(unsigned long adr)
    -{
    - unsigned long va, kva, ret;
    -
    - va = VMALLOC_VMADDR(adr);
    - kva = uvirt_to_kva(pgd_offset_k(va), va);
    - ret = __pa(kva);
    - MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static void *rvmalloc(unsigned long size)
    -{
    - void *mem;
    - unsigned long adr, page;
    -
    - /* Round it off to PAGE_SIZE */
    - size += (PAGE_SIZE - 1);
    - size &= ~(PAGE_SIZE - 1);
    -
    - mem = vmalloc(size);
    - if (!mem)
    - return NULL;
    -
    - memset(mem, 0, size); /* Clear the ram out, no junk to the user */
    - adr = (unsigned long) mem;
    - while (size > 0) {
    - page = kvirt_to_pa(adr);
    - mem_map_reserve(MAP_NR(__va(page)));
    - adr += PAGE_SIZE;
    - if (size > PAGE_SIZE)
    - size -= PAGE_SIZE;
    - else
    - size = 0;
    - }
    -
    - return mem;
    -}
    -
    -static void rvfree(void *mem, unsigned long size)
    -{
    - unsigned long adr, page;
    -
    - if (!mem)
    - return;
    -
    - size += (PAGE_SIZE - 1);
    - size &= ~(PAGE_SIZE - 1);
    -
    - adr=(unsigned long) mem;
    - while (size > 0) {
    - page = kvirt_to_pa(adr);
    - mem_map_unreserve(MAP_NR(__va(page)));
    - adr += PAGE_SIZE;
    - if (size > PAGE_SIZE)
    - size -= PAGE_SIZE;
    - else
    - size = 0;
    - }
    - vfree(mem);
    -}

    static int usb_cpia_get_version(struct usb_device *dev, void *buf)
    {
    diff -urN linux-2.3.43-8/drivers/usb/ibmcam.c linux/drivers/usb/ibmcam.c
    --- linux-2.3.43-8/drivers/usb/ibmcam.c Thu Feb 10 15:07:21 2000
    +++ linux/drivers/usb/ibmcam.c Thu Feb 10 18:33:38 2000
    @@ -143,124 +143,8 @@
    #define MAX_IBMCAM 4

    struct usb_ibmcam cams[MAX_IBMCAM];
    -
    -/*******************************/
    -/* Memory management functions */
    -/*******************************/
    -
    -#define MDEBUG(x) do { } while(0) /* Debug memory management */
    -
    static struct usb_driver ibmcam_driver;
    static void usb_ibmcam_release(struct usb_ibmcam *ibmcam);
    -
    -/* Given PGD from the address space's page table, return the kernel
    - * virtual mapping of the physical memory mapped at ADR.
    - */
    -static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
    -{
    - unsigned long ret = 0UL;
    - pmd_t *pmd;
    - pte_t *ptep, pte;
    -
    - if (!pgd_none(*pgd)) {
    - pmd = pmd_offset(pgd, adr);
    - if (!pmd_none(*pmd)) {
    - ptep = pte_offset(pmd, adr);
    - pte = *ptep;
    - if (pte_present(pte))
    - ret = page_address(pte_page(pte)) | (adr & (PAGE_SIZE-1));
    - }
    - }
    - MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static inline unsigned long uvirt_to_bus(unsigned long adr)
    -{
    - unsigned long kva, ret;
    -
    - kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
    - ret = virt_to_bus((void *)kva);
    - MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static inline unsigned long kvirt_to_bus(unsigned long adr)
    -{
    - unsigned long va, kva, ret;
    -
    - va = VMALLOC_VMADDR(adr);
    - kva = uvirt_to_kva(pgd_offset_k(va), va);
    - ret = virt_to_bus((void *)kva);
    - MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -/* Here we want the physical address of the memory.
    - * This is used when initializing the contents of the
    - * area and marking the pages as reserved.
    - */
    -static inline unsigned long kvirt_to_pa(unsigned long adr)
    -{
    - unsigned long va, kva, ret;
    -
    - va = VMALLOC_VMADDR(adr);
    - kva = uvirt_to_kva(pgd_offset_k(va), va);
    - ret = __pa(kva);
    - MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static void *rvmalloc(unsigned long size)
    -{
    - void *mem;
    - unsigned long adr, page;
    -
    - /* Round it off to PAGE_SIZE */
    - size += (PAGE_SIZE - 1);
    - size &= ~(PAGE_SIZE - 1);
    -
    - mem = vmalloc(size);
    - if (!mem)
    - return NULL;
    -
    - memset(mem, 0, size); /* Clear the ram out, no junk to the user */
    - adr = (unsigned long) mem;
    - while (size > 0) {
    - page = kvirt_to_pa(adr);
    - mem_map_reserve(MAP_NR(__va(page)));
    - adr += PAGE_SIZE;
    - if (size > PAGE_SIZE)
    - size -= PAGE_SIZE;
    - else
    - size = 0;
    - }
    -
    - return mem;
    -}
    -
    -static void rvfree(void *mem, unsigned long size)
    -{
    - unsigned long adr, page;
    -
    - if (!mem)
    - return;
    -
    - size += (PAGE_SIZE - 1);
    - size &= ~(PAGE_SIZE - 1);
    -
    - adr=(unsigned long) mem;
    - while (size > 0) {
    - page = kvirt_to_pa(adr);
    - mem_map_unreserve(MAP_NR(__va(page)));
    - adr += PAGE_SIZE;
    - if (size > PAGE_SIZE)
    - size -= PAGE_SIZE;
    - else
    - size = 0;
    - }
    - vfree(mem);
    -}

    /*
    * usb_ibmcam_overlaychar()
    diff -urN linux-2.3.43-8/drivers/usb/ov511.c linux/drivers/usb/ov511.c
    --- linux-2.3.43-8/drivers/usb/ov511.c Thu Feb 10 15:07:21 2000
    +++ linux/drivers/usb/ov511.c Thu Feb 10 18:37:11 2000
    @@ -79,122 +79,7 @@

    char kernel_version[] = UTS_RELEASE;

    -/*******************************/
    -/* Memory management functions */
    -/*******************************/
    -
    -#define MDEBUG(x) do { } while(0) /* Debug memory management */
    -
    static struct usb_driver ov511_driver;
    -
    -/* Given PGD from the address space's page table, return the kernel
    - * virtual mapping of the physical memory mapped at ADR.
    - */
    -static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
    -{
    - unsigned long ret = 0UL;
    - pmd_t *pmd;
    - pte_t *ptep, pte;
    -
    - if (!pgd_none(*pgd)) {
    - pmd = pmd_offset(pgd, adr);
    - if (!pmd_none(*pmd)) {
    - ptep = pte_offset(pmd, adr);
    - pte = *ptep;
    - if (pte_present(pte))
    - ret = page_address(pte_page(pte)) | (adr & (PAGE_SIZE-1));
    - }
    - }
    - MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static inline unsigned long uvirt_to_bus(unsigned long adr)
    -{
    - unsigned long kva, ret;
    -
    - kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
    - ret = virt_to_bus((void *)kva);
    - MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static inline unsigned long kvirt_to_bus(unsigned long adr)
    -{
    - unsigned long va, kva, ret;
    -
    - va = VMALLOC_VMADDR(adr);
    - kva = uvirt_to_kva(pgd_offset_k(va), va);
    - ret = virt_to_bus((void *)kva);
    - MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -/* Here we want the physical address of the memory.
    - * This is used when initializing the contents of the
    - * area and marking the pages as reserved.
    - */
    -static inline unsigned long kvirt_to_pa(unsigned long adr)
    -{
    - unsigned long va, kva, ret;
    -
    - va = VMALLOC_VMADDR(adr);
    - kva = uvirt_to_kva(pgd_offset_k(va), va);
    - ret = __pa(kva);
    - MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
    - return ret;
    -}
    -
    -static void *rvmalloc(unsigned long size)
    -{
    - void *mem;
    - unsigned long adr, page;
    -
    - /* Round it off to PAGE_SIZE */
    - size += (PAGE_SIZE - 1);
    - size &= ~(PAGE_SIZE - 1);
    -
    - mem = vmalloc(size);
    - if (!mem)
    - return NULL;
    -
    - memset(mem, 0, size); /* Clear the ram out, no junk to the user */
    - adr = (unsigned long) mem;
    - while (size > 0) {
    - page = kvirt_to_pa(adr);
    - mem_map_reserve(MAP_NR(__va(page)));
    - adr += PAGE_SIZE;
    - if (size > PAGE_SIZE)
    - size -= PAGE_SIZE;
    - else
    - size = 0;
    - }
    -
    - return mem;
    -}
    -
    -static void rvfree(void *mem, unsigned long size)
    -{
    - unsigned long adr, page;
    -
    - if (!mem)
    - return;
    -
    - size += (PAGE_SIZE - 1);
    - size &= ~(PAGE_SIZE - 1);
    -
    - adr=(unsigned long) mem;
    - while (size > 0) {
    - page = kvirt_to_pa(adr);
    - mem_map_unreserve(MAP_NR(__va(page)));
    - adr += PAGE_SIZE;
    - if (size > PAGE_SIZE)
    - size -= PAGE_SIZE;
    - else
    - size = 0;
    - }
    - vfree(mem);
    -}

    int ov511_reg_write(struct usb_device *dev, unsigned char reg, unsigned char value)
    {
    diff -urN linux-2.3.43-8/include/linux/vmalloc.h linux/include/linux/vmalloc.h
    --- linux-2.3.43-8/include/linux/vmalloc.h Wed Nov 24 11:04:30 1999
    +++ linux/include/linux/vmalloc.h Thu Feb 10 19:03:23 2000
    @@ -23,7 +23,10 @@
    long vread(char *buf, char *addr, unsigned long count);
    void vmfree_area_pages(unsigned long address, unsigned long size);
    int vmalloc_area_pages(unsigned long address, unsigned long size);
    +inline unsigned long kvirt_to_bus(unsigned long adr);
    +inline unsigned long kvirt_to_pa(unsigned long adr);
    +void *rvmalloc(unsigned long size);
    +void rvfree(void *mem, unsigned long size);

    extern struct vm_struct * vmlist;
    #endif
    -
    diff -urN linux-2.3.43-8/mm/vmalloc.c linux/mm/vmalloc.c
    --- linux-2.3.43-8/mm/vmalloc.c Wed Nov 24 11:04:31 1999
    +++ linux/mm/vmalloc.c Thu Feb 10 19:12:22 2000
    @@ -7,9 +7,11 @@

    #include <linux/malloc.h>
    #include <linux/vmalloc.h>
    +#include <linux/wrapper.h>

    #include <asm/uaccess.h>
    #include <asm/pgalloc.h>
    +#include <asm/io.h>

    struct vm_struct * vmlist = NULL;

    @@ -258,4 +260,127 @@
    }
    finished:
    return buf - buf_start;
    +}
    +
    +/* [DaveM] I've recoded most of this so that:
    + * 1) It's easier to tell what is happening
    + * 2) It's more portable, especially for translating things
    + * out of vmalloc mapped areas in the kernel.
    + * 3) Less unnecessary translations happen.
    + *
    + * The code used to assume that the kernel vmalloc mappings
    + * existed in the page tables of every process, this is simply
    + * not guarenteed. We now use pgd_offset_k which is the
    + * defined way to get at the kernel page tables.
    + */
    +
    +#define MDEBUG(x) do { } while(0) /* Debug memory management */
    +
    +/* Given PGD from the address space's page table, return the kernel
    + * virtual mapping of the physical memory mapped at ADR.
    + */
    +static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
    +{
    + unsigned long ret = 0UL;
    + pmd_t *pmd;
    + pte_t *ptep, pte;
    +
    + if (!pgd_none(*pgd)) {
    + pmd = pmd_offset(pgd, adr);
    + if (!pmd_none(*pmd)) {
    + ptep = pte_offset(pmd, adr);
    + pte = *ptep;
    + if (pte_present(pte))
    + ret = page_address(pte_page(pte)) | (adr & (PAGE_SIZE-1));
    + }
    + }
    + MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
    + return ret;
    +}
    +
    +static inline unsigned long uvirt_to_bus(unsigned long adr)
    +{
    + unsigned long kva, ret;
    +
    + kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
    + ret = virt_to_bus((void *)kva);
    + MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
    + return ret;
    +}
    +
    +inline unsigned long kvirt_to_bus(unsigned long adr)
    +{
    + unsigned long va, kva, ret;
    +
    + va = VMALLOC_VMADDR(adr);
    + kva = uvirt_to_kva(pgd_offset_k(va), va);
    + ret = virt_to_bus((void *)kva);
    + MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
    + return ret;
    +}
    +
    +/* Here we want the physical address of the memory.
    + * This is used when initializing the contents of the
    + * area and marking the pages as reserved.
    + */
    +inline unsigned long kvirt_to_pa(unsigned long adr)
    +{
    + unsigned long va, kva, ret;
    +
    + va = VMALLOC_VMADDR(adr);
    + kva = uvirt_to_kva(pgd_offset_k(va), va);
    + ret = __pa(kva);
    + MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
    + return ret;
    +}
    +
    +void *rvmalloc(unsigned long size)
    +{
    + void *mem;
    + unsigned long adr, page;
    +
    + /* Round it off to PAGE_SIZE */
    + size += (PAGE_SIZE - 1);
    + size &= ~(PAGE_SIZE - 1);
    +
    + mem = vmalloc(size);
    + if (!mem)
    + return NULL;
    +
    + memset(mem, 0, size); /* Clear the ram out, no junk to the user */
    + adr = (unsigned long) mem;
    + while (size > 0) {
    + page = kvirt_to_pa(adr);
    + mem_map_reserve(MAP_NR(__va(page)));
    + adr += PAGE_SIZE;
    + if (size > PAGE_SIZE)
    + size -= PAGE_SIZE;
    + else
    + size = 0;
    + }
    +
    + return mem;
    +}
    +
    +void rvfree(void *mem, unsigned long size)
    +{
    + unsigned long adr, page;
    +
    + if (!mem)
    + return;
    +
    + size += (PAGE_SIZE - 1);
    + size &= ~(PAGE_SIZE - 1);
    +
    + adr=(unsigned long) mem;
    + while (size > 0) {
    + page = kvirt_to_pa(adr);
    + mem_map_unreserve(MAP_NR(__va(page)));
    + adr += PAGE_SIZE;
    + if (size > PAGE_SIZE)
    + size -= PAGE_SIZE;
    + else
    + size = 0;
    + }
    + vfree(mem);
    }

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:56    [W:0.062 / U:0.072 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site