diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2014-10-07 08:02:35 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:12:15 -0400 |
commit | 1d9fba8804fb811771eac0f68f334f51f101ed01 (patch) | |
tree | 0be143d6fd550db0e4aba15e2ae4d76117d37ad8 /drivers/gpu/nvgpu/gk20a/gk20a_allocator.c | |
parent | c0668f05ea1e2429444d6aad2a40dda81aba7ec8 (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.c | 22 |
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 */ |
22 | int gk20a_allocator_init(struct gk20a_allocator *allocator, | 22 | int 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 | */ |
67 | int gk20a_allocator_block_alloc(struct gk20a_allocator *allocator, | 65 | int 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 */ |
108 | int gk20a_allocator_block_free(struct gk20a_allocator *allocator, | 106 | int 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 | ||