summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2014-10-07 08:02:35 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:12:15 -0400
commit1d9fba8804fb811771eac0f68f334f51f101ed01 (patch)
tree0be143d6fd550db0e4aba15e2ae4d76117d37ad8 /drivers/gpu/nvgpu/gk20a/gk20a_allocator.c
parentc0668f05ea1e2429444d6aad2a40dda81aba7ec8 (diff)
gpu: nvgpu: Per-alloc alignment
Change-Id: I8b7e86afb68adf6dd33b05995d0978f42d57e7b7 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/554185 GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a_allocator.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a_allocator.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c b/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c
index 0b5f9f6f..fee3e4ea 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c
@@ -20,7 +20,7 @@
20 20
21/* init allocator struct */ 21/* init allocator struct */
22int gk20a_allocator_init(struct gk20a_allocator *allocator, 22int gk20a_allocator_init(struct gk20a_allocator *allocator,
23 const char *name, u32 start, u32 len, u32 align) 23 const char *name, u32 start, u32 len)
24{ 24{
25 memset(allocator, 0, sizeof(struct gk20a_allocator)); 25 memset(allocator, 0, sizeof(struct gk20a_allocator));
26 26
@@ -28,16 +28,14 @@ int gk20a_allocator_init(struct gk20a_allocator *allocator,
28 28
29 allocator->base = start; 29 allocator->base = start;
30 allocator->limit = start + len - 1; 30 allocator->limit = start + len - 1;
31 allocator->align = align;
32 31
33 allocator->bitmap = kzalloc(BITS_TO_LONGS(len) * sizeof(long), 32 allocator->bitmap = kzalloc(BITS_TO_LONGS(len) * sizeof(long),
34 GFP_KERNEL); 33 GFP_KERNEL);
35 if (!allocator->bitmap) 34 if (!allocator->bitmap)
36 return -ENOMEM; 35 return -ENOMEM;
37 36
38 allocator_dbg(allocator, "%s : base %d, limit %d, align %d", 37 allocator_dbg(allocator, "%s : base %d, limit %d",
39 allocator->name, allocator->base, 38 allocator->name, allocator->base);
40 allocator->limit, allocator->align);
41 39
42 init_rwsem(&allocator->rw_sema); 40 init_rwsem(&allocator->rw_sema);
43 41
@@ -65,7 +63,7 @@ void gk20a_allocator_destroy(struct gk20a_allocator *allocator)
65 * contiguous address. 63 * contiguous address.
66*/ 64*/
67int gk20a_allocator_block_alloc(struct gk20a_allocator *allocator, 65int gk20a_allocator_block_alloc(struct gk20a_allocator *allocator,
68 u32 *addr, u32 len) 66 u32 *addr, u32 len, u32 align)
69{ 67{
70 unsigned long _addr; 68 unsigned long _addr;
71 69
@@ -73,11 +71,11 @@ int gk20a_allocator_block_alloc(struct gk20a_allocator *allocator,
73 71
74 if ((*addr != 0 && *addr < allocator->base) || /* check addr range */ 72 if ((*addr != 0 && *addr < allocator->base) || /* check addr range */
75 *addr + len > allocator->limit || /* check addr range */ 73 *addr + len > allocator->limit || /* check addr range */
76 *addr & (allocator->align - 1) || /* check addr alignment */ 74 *addr & (align - 1) || /* check addr alignment */
77 len == 0) /* check len */ 75 len == 0) /* check len */
78 return -EINVAL; 76 return -EINVAL;
79 77
80 len = ALIGN(len, allocator->align); 78 len = ALIGN(len, align);
81 if (!len) 79 if (!len)
82 return -ENOMEM; 80 return -ENOMEM;
83 81
@@ -87,7 +85,7 @@ int gk20a_allocator_block_alloc(struct gk20a_allocator *allocator,
87 allocator->limit - allocator->base + 1, 85 allocator->limit - allocator->base + 1,
88 *addr ? (*addr - allocator->base) : 0, 86 *addr ? (*addr - allocator->base) : 0,
89 len, 87 len,
90 allocator->align - 1); 88 align - 1);
91 if ((_addr > allocator->limit - allocator->base + 1) || 89 if ((_addr > allocator->limit - allocator->base + 1) ||
92 (*addr && *addr != (_addr + allocator->base))) { 90 (*addr && *addr != (_addr + allocator->base))) {
93 up_write(&allocator->rw_sema); 91 up_write(&allocator->rw_sema);
@@ -106,16 +104,16 @@ int gk20a_allocator_block_alloc(struct gk20a_allocator *allocator,
106 104
107/* free all blocks between start and end */ 105/* free all blocks between start and end */
108int gk20a_allocator_block_free(struct gk20a_allocator *allocator, 106int gk20a_allocator_block_free(struct gk20a_allocator *allocator,
109 u32 addr, u32 len) 107 u32 addr, u32 len, u32 align)
110{ 108{
111 allocator_dbg(allocator, "[in] addr %d, len %d", addr, len); 109 allocator_dbg(allocator, "[in] addr %d, len %d", addr, len);
112 110
113 if (addr + len > allocator->limit || /* check addr range */ 111 if (addr + len > allocator->limit || /* check addr range */
114 addr < allocator->base || 112 addr < allocator->base ||
115 addr & (allocator->align - 1)) /* check addr alignment */ 113 addr & (align - 1)) /* check addr alignment */
116 return -EINVAL; 114 return -EINVAL;
117 115
118 len = ALIGN(len, allocator->align); 116 len = ALIGN(len, align);
119 if (!len) 117 if (!len)
120 return -EINVAL; 118 return -EINVAL;
121 119