diff options
author | Robert Tivy <rtivy@ti.com> | 2014-01-17 17:25:49 -0800 |
---|---|---|
committer | Chris Ring <cring@ti.com> | 2014-01-21 08:22:29 -0800 |
commit | 317792d2c18c1144401e2aee689aadebbd3a9b12 (patch) | |
tree | dad587bb0b62b8d1b06025d46d2612678a6e5c58 | |
parent | c6080eb94fea4c243b7802b1ea2cff4c34319a27 (diff) | |
download | linuxutils-317792d2c18c1144401e2aee689aadebbd3a9b12.tar.gz |
Allow bigger sizes for CMEM_getBlock and CMEM_getPool4.00.02.114.00.02.10_eng
CMEM_getBlock() (and CMEM_getBlockAttrs) was broken for the new extended
blocks. The interface has been changed to allow for returning a size
greater than the value that will fit in a 'size_t' type.
CMEM_getPool() did not allow a size greater than the value that will fit
in a 'size_t' type. This API has been changed to allow specifying an
extended size, to support pools with an extended buffer size.
-rw-r--r-- | include/ti/cmem.h | 16 | ||||
-rw-r--r-- | src/cmem/api/cmem.c | 48 | ||||
-rw-r--r-- | src/cmem/module/cmemk.c | 55 | ||||
-rw-r--r-- | src/cmem/tests/apitest.c | 39 |
4 files changed, 89 insertions, 69 deletions
diff --git a/include/ti/cmem.h b/include/ti/cmem.h index 6174d37..ae00753 100644 --- a/include/ti/cmem.h +++ b/include/ti/cmem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (c) 2007-2014 Texas Instruments Incorporated - http://www.ti.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -296,7 +296,7 @@ extern CMEM_AllocParams CMEM_DEFAULTPARAMS; typedef struct CMEM_BlockAttrs { off_t phys_base; - size_t size; + unsigned long long size; } CMEM_BlockAttrs; /** @cond INTERNAL */ @@ -318,16 +318,16 @@ union CMEM_AllocUnion { int blockid; } get_size_inparams; /**< */ struct { /**< */ - size_t size; + unsigned long long size; int blockid; } get_pool_inparams; /**< */ struct { /**< */ unsigned long long physp; - size_t size; + unsigned long long size; } alloc_pool_outparams; /**< */ struct { /**< */ unsigned long long physp; - size_t size; + unsigned long long size; } get_block_outparams; /**< */ struct { /**< */ int poolid; @@ -366,7 +366,7 @@ int CMEM_init(void); * @sa CMEM_free() * @sa CMEM_getPool2() */ -int CMEM_getPool(size_t size); +int CMEM_getPool(unsigned long long size); /** * @brief Find the pool in memory block blockid that best fits a given @@ -384,7 +384,7 @@ int CMEM_getPool(size_t size); * @sa CMEM_free() * @sa CMEM_getPool() */ -int CMEM_getPool2(int blockid, size_t size); +int CMEM_getPool2(int blockid, unsigned long long size); /** * @brief Allocate memory from a specified pool. @@ -797,7 +797,7 @@ int CMEM_getVersion(void); * @sa CMEM_getBlockAttrs() * @sa CMEM_getNumBlocks() */ -int CMEM_getBlock(off_t *pphys_base, size_t *psize); +int CMEM_getBlock(off_t *pphys_base, unsigned long long *psize); /** * @brief Retrieve extended memory block attributes from CMEM driver diff --git a/src/cmem/api/cmem.c b/src/cmem/api/cmem.c index 6853a17..c4140ec 100644 --- a/src/cmem/api/cmem.c +++ b/src/cmem/api/cmem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (c) 2007-2014 Texas Instruments Incorporated - http://www.ti.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -67,7 +67,7 @@ struct block_struct { static int cmem_fd = -2; static int ref_count = 0; -static void *getAndAllocFromPool(int blockid, size_t size, CMEM_AllocParams *params, off_t *physp); +static void *getAndAllocFromPool(int blockid, unsigned long long size, CMEM_AllocParams *params, off_t *physp); static void *allocFromHeap(int blockid, size_t size, CMEM_AllocParams *params, off_t *physp); static void *allocFromPool(int blockid, int poolid, CMEM_AllocParams *params, off_t *physp); @@ -158,7 +158,8 @@ static void *allocFromPool(int blockid, int poolid, CMEM_AllocParams *params, of union CMEM_AllocUnion allocDesc; off_t phys; void *userp; - size_t size; + unsigned long long size; + size_t map_size; unsigned int cmd; int rv; @@ -179,7 +180,7 @@ static void *allocFromPool(int blockid, int poolid, CMEM_AllocParams *params, of phys = (off_t)allocDesc.alloc_pool_outparams.physp; size = allocDesc.alloc_pool_outparams.size; - __D("allocPool: allocated phys buffer %#llx, size %#x\n", + __D("allocPool: allocated phys buffer %#llx, size %#llx\n", (unsigned long long)phys, size); /* non-NULL physp means "don't map", return NULL since no virt ptr */ @@ -188,13 +189,22 @@ static void *allocFromPool(int blockid, int poolid, CMEM_AllocParams *params, of return NULL; } + map_size = (size_t)size; + if (map_size != size) { + __E("allocPool: returned pool buffer too big for mmap (size %#llx)\n", + size); + __E(" Freeing phys buffer %#llx\n", (unsigned long long)phys); + ioctl(cmem_fd, CMEM_IOCFREEPHYS | CMEM_IOCMAGIC , &phys); + return NULL; + } + /* Map the physical address to user space */ userp = mmap(0, // Preferred start address - size, // Length to be mapped + map_size, // Length to be mapped PROT_WRITE | PROT_READ, // Read and write access MAP_SHARED, // Shared memory cmem_fd, // File descriptor - phys); // The byte offset from fd + phys); // The byte offset from fd if (userp == MAP_FAILED) { __E("allocPool: Failed to mmap buffer at physical address %#llx\n", @@ -209,7 +219,7 @@ static void *allocFromPool(int blockid, int poolid, CMEM_AllocParams *params, of return userp; } -static void *getAndAllocFromPool(int blockid, size_t size, CMEM_AllocParams *params, off_t *physp) +static void *getAndAllocFromPool(int blockid, unsigned long long size, CMEM_AllocParams *params, off_t *physp) { int poolid; @@ -223,7 +233,7 @@ static void *getAndAllocFromPool(int blockid, size_t size, CMEM_AllocParams *par return NULL; } if (poolid == -2) { - return allocFromHeap(blockid, size, params, physp); + return allocFromHeap(blockid, (size_t)size, params, physp); } else { return allocFromPool(blockid, poolid, params, physp); @@ -316,7 +326,7 @@ static void *alloc(int blockid, size_t size, CMEM_AllocParams *params, off_t *ph } if (params->type == CMEM_POOL) { - return getAndAllocFromPool(blockid, size, params, physp); + return getAndAllocFromPool(blockid, (unsigned long long)size, params, physp); } else { return allocFromHeap(blockid, size, params, physp); @@ -554,7 +564,7 @@ int CMEM_unregister(void *ptr, CMEM_AllocParams *params) return CMEM_free(ptr, params); } -static int getPoolFromBlock(int blockid, size_t size) +static int getPoolFromBlock(int blockid, unsigned long long size) { union CMEM_AllocUnion poolDesc; @@ -565,7 +575,7 @@ static int getPoolFromBlock(int blockid, size_t size) poolDesc.get_pool_inparams.size = size; poolDesc.get_pool_inparams.blockid = blockid; if (ioctl(cmem_fd, CMEM_IOCGETPOOL | CMEM_IOCMAGIC, &poolDesc) == -1) { - __E("getPool: Failed to get a pool fitting a size %d\n", size); + __E("getPool: Failed to get a pool fitting a size %#llx\n", size); return -1; } @@ -575,16 +585,16 @@ static int getPoolFromBlock(int blockid, size_t size) return poolDesc.poolid; } -int CMEM_getPool(size_t size) +int CMEM_getPool(unsigned long long size) { - __D("getPool: entered w/ size %#x\n", size); + __D("getPool: entered w/ size %#llx\n", size); return getPoolFromBlock(0, size); } -int CMEM_getPool2(int blockid, size_t size) +int CMEM_getPool2(int blockid, unsigned long long size) { - __D("getPool2: entered w/ size %#x\n", size); + __D("getPool2: entered w/ size %#llx\n", size); return getPoolFromBlock(blockid, size); } @@ -706,7 +716,7 @@ int CMEM_getVersion(void) return version; } -static int getBlock(int blockid, off_t *pphys_base, size_t *psize) +static int getBlock(int blockid, off_t *pphys_base, unsigned long long *psize) { union CMEM_AllocUnion block; int rv; @@ -730,13 +740,13 @@ static int getBlock(int blockid, off_t *pphys_base, size_t *psize) *psize = block.get_block_outparams.size; __D("getBlock: exiting, ioctl CMEM_IOCGETBLOCK succeeded, " - "returning *pphys_base=%#llx, *psize=%#x\n", + "returning *pphys_base=%#llx, *psize=%#llx\n", (unsigned long long)(*pphys_base), *psize); return 0; } -int CMEM_getBlock(off_t *pphys_base, size_t *psize) +int CMEM_getBlock(off_t *pphys_base, unsigned long long *psize) { return getBlock(0, pphys_base, psize); } @@ -758,7 +768,7 @@ int CMEM_getNumBlocks(int *pnblocks) rv = ioctl(cmem_fd, CMEM_IOCGETNUMBLOCKS | CMEM_IOCMAGIC, pnblocks); if (rv != 0) { - __E("getBlock: Failed to retrieve number of blocks " + __E("getNumBlocks: Failed to retrieve number of blocks " "from driver: %d.\n", rv); return -1; diff --git a/src/cmem/module/cmemk.c b/src/cmem/module/cmemk.c index cf968a2..7cf86af 100644 --- a/src/cmem/module/cmemk.c +++ b/src/cmem/module/cmemk.c @@ -1165,7 +1165,8 @@ static long ioctl(struct file *filp, unsigned int cmd, unsigned long args) dma_addr_t dma = 0; size_t reqsize, align; size_t size = 0; - int delta = MAXTYPE(int); + unsigned long long lsize, lreqsize; + unsigned long long delta = MAXTYPE(unsigned long long); int pool = -1; int i; int bi; @@ -1290,7 +1291,7 @@ alloc: } __D("ALLOCHEAP%s: allocated %#x size buffer at %#llx (phys address)\n", - cmd & CMEM_CACHED ? "CACHED" : "", entry->size, + cmd & CMEM_CACHED ? "CACHED" : "", (size_t)entry->size, (unsigned long long)entry->physp); break; @@ -1327,7 +1328,7 @@ alloc: } if (bi == NBLOCKS) { - size = p_objs[bi][pool].size; + lsize = p_objs[bi][pool].size; dev = &cmem_cma_dev[pool]; align = 0; pool_alloc = 1; @@ -1427,7 +1428,7 @@ alloc: if (entry) { /* record values in case entry gets kfree()'d for CMEM_HEAP */ id = entry->id; - size = entry->size; + size = (size_t)entry->size; registeredlistp = &entry->users; u = registeredlistp->next; @@ -1483,11 +1484,11 @@ alloc: } if (bi == NBLOCKS) { - dma_free_coherent(entry->dev, entry->size, + dma_free_coherent(entry->dev, (size_t)entry->size, entry->kvirtp, entry->dma); } else { - HeapMem_free(bi, entry->physp, entry->size); + HeapMem_free(bi, entry->physp, (size_t)entry->size); } list_del(e); kfree(entry); @@ -1594,7 +1595,7 @@ alloc: if (put_user(p_objs[bi][pool].size, argp)) { return -EFAULT; } - __D("GETSIZE returning %d\n", p_objs[bi][pool].size); + __D("GETSIZE returning %#llx\n", p_objs[bi][pool].size); break; /* @@ -1607,7 +1608,7 @@ alloc: return -EFAULT; } - reqsize = allocDesc.get_pool_inparams.size; + lreqsize = allocDesc.get_pool_inparams.size; bi = allocDesc.get_pool_inparams.blockid; if (bi == CMEM_CMABLOCKID) { @@ -1624,28 +1625,29 @@ alloc: return -ERESTARTSYS; } - __D("GETPOOL: Trying to find a pool to fit size %d\n", reqsize); + __D("GETPOOL: Trying to find a pool to fit size %#llx\n", lreqsize); for (i = 0; i < npools[bi]; i++) { - size = p_objs[bi][i].size; + lsize = p_objs[bi][i].size; freelistp = &p_objs[bi][i].freelist; - __D("GETPOOL: size (%d) > reqsize (%d)?\n", size, reqsize); - if (size >= reqsize) { - __D("GETPOOL: delta (%d) < olddelta (%d)?\n", - size - reqsize, delta); - if ((size - reqsize) < delta) { + __D("GETPOOL: size (%#llx) > reqsize (%#llx)?\n", + lsize, lreqsize); + if (lsize >= lreqsize) { + __D("GETPOOL: delta (%#llx) < olddelta (%#llx)?\n", + lsize - lreqsize, delta); + if ((lsize - lreqsize) < delta) { if (bi < NBLOCKS) { if (!list_empty(freelistp)) { - delta = size - reqsize; + delta = lsize - lreqsize; pool = i; - __D("GETPOOL: Found a best fit delta %d in pool %d\n", + __D("GETPOOL: Found a best fit delta %#llx in pool %d\n", delta, pool); } } else { - delta = size - reqsize; + delta = lsize - lreqsize; pool = i; - __D("GETPOOL: Found a best fit delta %d in CMA block\n", + __D("GETPOOL: Found a best fit delta %#llx in CMA block\n", delta); } } @@ -1656,6 +1658,7 @@ alloc: if (useHeapIfPoolUnavailable) { /* no pool buffer available, try heap */ + reqsize = lreqsize; physp = HeapMem_alloc(bi, reqsize, HEAP_ALIGN, DRYRUN); if (physp != 0) { /* @@ -1675,7 +1678,7 @@ alloc: mutex_unlock(&cmem_mutex); if (pool == -1) { - __E("Failed to find a pool which fits %d\n", reqsize); + __E("Failed to find a pool which fits %#llx\n", lreqsize); return -ENOMEM; } @@ -1814,7 +1817,7 @@ alloc: block_start[bi]; __D("GETBLOCK: returning phys base " - "%#llx, size %#x.\n", allocDesc.get_block_outparams.physp, + "%#llx, size %#llx.\n", allocDesc.get_block_outparams.physp, allocDesc.get_block_outparams.size); if (copy_to_user(argp, &allocDesc, sizeof(allocDesc))) { @@ -1886,11 +1889,12 @@ static int mmap(struct file *filp, struct vm_area_struct *vma) { phys_addr_t physp; struct pool_buffer *entry; - size_t size = vma->vm_end - vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; + size_t s; __D("mmap: vma->vm_start = %#lx\n", vma->vm_start); __D("mmap: vma->vm_end = %#lx\n", vma->vm_end); - __D("mmap: size = %#llx\n", (unsigned long long)size); + __D("mmap: size = %#lx\n", size); __D("mmap: vma->vm_pgoff = %#lx\n", vma->vm_pgoff); physp = (unsigned long long)vma->vm_pgoff << PAGE_SHIFT; @@ -1899,7 +1903,8 @@ static int mmap(struct file *filp, struct vm_area_struct *vma) return -ERESTARTSYS; } - entry = find_busy_entry(physp, NULL, NULL, NULL, &size); + s = size; + entry = find_busy_entry(physp, NULL, NULL, NULL, &s); mutex_unlock(&cmem_mutex); if (entry != NULL) { @@ -2349,7 +2354,7 @@ int __init cmem_init(void) cmem_cma_dev[i].coherent_dma_mask = DMA_BIT_MASK(32); - __D(" pool %d: size=%#x numbufs=%d\n", i, + __D(" pool %d: size=%#llx numbufs=%d\n", i, p_objs[NBLOCKS][i].size, p_objs[NBLOCKS][i].numbufs); } diff --git a/src/cmem/tests/apitest.c b/src/cmem/tests/apitest.c index dc48e20..750f211 100644 --- a/src/cmem/tests/apitest.c +++ b/src/cmem/tests/apitest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (c) 2007-2014 Texas Instruments Incorporated - http://www.ti.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -54,7 +54,7 @@ unsigned int *ptrs[NUMHEAPPTRS]; int nblocks; -int writereadCMA(int size) +int writereadCMA(size_t size) { int rv; int i; @@ -107,7 +107,7 @@ int writereadCMA(int size) return 0; } -void testCMA(int size) +void testCMA(size_t size) { int rv; int num_buffers; @@ -169,7 +169,7 @@ void testCMA(int size) } -void testHeap(int size, int block) +void testHeap(size_t size, int block) { int rv; int num_buffers; @@ -225,7 +225,7 @@ void testHeap(int size, int block) printf("...done\n"); } -void testPools(int size, int block) +void testPools(size_t size, int block) { int rv; int num_buffers; @@ -281,7 +281,7 @@ void testPools(int size, int block) printf("...done\n"); } -void testCache(int size, int block) +void testCache(size_t size, int block) { unsigned int *ptr1_nocache = NULL; unsigned int *ptr1_cache = NULL; @@ -324,7 +324,7 @@ void testCache(int size, int block) (unsigned long long)physp_nocache); /* Write some data into this buffer */ - for (i=0; i < size / sizeof(int) ; i++) { + for (i=0; i < size / sizeof(size_t) ; i++) { ptr1_nocache[i] = 0xbeefbeef; } @@ -356,7 +356,7 @@ void testCache(int size, int block) (unsigned long long)physp_cache); /* Write some data into this buffer */ - for (i = 0; i < size / sizeof(int); i++) { + for (i = 0; i < size / sizeof(size_t); i++) { ptr1_cache[i] = 0x0dead1ce; } @@ -386,7 +386,7 @@ void testCache(int size, int block) (unsigned long long)physp_dma); /* Initialize DMA source buffer */ - for (i = 0; i < size / sizeof(int); i++) { + for (i = 0; i < size / sizeof(size_t); i++) { ptr1_cache[i] = 0x0dead1ce; } @@ -399,7 +399,7 @@ void testCache(int size, int block) printf("R-M-W noncached buffer %#llx\n", (unsigned long long)physp_nocache); gettimeofday(&start_tv, NULL); - for (i = 0; i < (size / sizeof(int)); i += 1) { + for (i = 0; i < (size / sizeof(size_t)); i += 1) { ptr1_nocache[i] += 1; } gettimeofday(&end_tv, NULL); @@ -411,7 +411,7 @@ void testCache(int size, int block) printf("R-M-W cached buffer %#llx\n", (unsigned long long)physp_cache); gettimeofday(&start_tv, NULL); - for (i = 0; i < (size / sizeof(int)); i += 1) { + for (i = 0; i < (size / sizeof(size_t)); i += 1) { ptr1_cache[i] += 1; } gettimeofday(&end_tv, NULL); @@ -435,7 +435,7 @@ void testCache(int size, int block) printf("R-M-W cached buffer %#llx\n", (unsigned long long)physp_cache); gettimeofday(&start_tv, NULL); - for (i = 0; i < (size / sizeof(int)); i += 1) { + for (i = 0; i < (size / sizeof(size_t)); i += 1) { ptr1_cache[i] += 1; } gettimeofday(&end_tv, NULL); @@ -485,7 +485,7 @@ void testCache(int size, int block) (unsigned long long)physp); /* Write some data into this buffer */ - for (i=0; i < size / sizeof(int); i++) { + for (i=0; i < size / sizeof(size_t); i++) { ptr2[i] = 0xfeebfeeb; } @@ -532,7 +532,7 @@ cleanup: } } -int testMap(int size) +int testMap(size_t size) { int *ptr; int *map_ptr; @@ -542,6 +542,11 @@ int testMap(int size) ptr = CMEM_alloc(size, NULL); printf("testMap: ptr = %p\n", ptr); + if (ptr == NULL) { + printf("testMap: CMEM_alloc() failed\n"); + return 1; + } + printf(" writing 0xdadaface to *ptr\n"); *ptr = 0xdadaface; @@ -588,7 +593,7 @@ cleanup: return ret; } -int testAllocPhys(int size) +int testAllocPhys(size_t size) { int *map_ptr; off_t physp; @@ -634,7 +639,7 @@ cleanup: int main(int argc, char *argv[]) { - int size; + size_t size; int version; CMEM_BlockAttrs attrs; int i; @@ -685,7 +690,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Failed to retrieve CMEM memory block %d bounds\n", i); } else { - printf("CMEM memory block %d: phys start = %#llx, size = %#x\n", + printf("CMEM memory block %d: phys start = %#llx, size = %#llx\n", i, (unsigned long long)attrs.phys_base, attrs.size); } |