summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2015-05-18 15:26:52 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2015-06-09 14:14:34 -0400
commitc5367d735066b67798686ccf304753fb52fccb68 (patch)
tree2aa2df02a325be5fe633ba5ce5db21aa1aeda500
parent6085c90f499c642bc41a646b0efbdfe60e096c74 (diff)
gpu: nvgpu: Do not pre-allocate cmdbuf entries
Do not preallocate cmdbuf tracking entries. Allocate them only when needed. Bug 200104160 Change-Id: I12f8392723c301a368af1e280893ff993480477f Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/743953 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/755148
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c50
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.h1
2 files changed, 8 insertions, 43 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 5a71e874..8ad1dcca 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -1116,8 +1116,7 @@ static int channel_gk20a_alloc_priv_cmdbuf(struct channel_gk20a *c)
1116 struct device *d = dev_from_gk20a(c->g); 1116 struct device *d = dev_from_gk20a(c->g);
1117 struct vm_gk20a *ch_vm = c->vm; 1117 struct vm_gk20a *ch_vm = c->vm;
1118 struct priv_cmd_queue *q = &c->priv_cmd_q; 1118 struct priv_cmd_queue *q = &c->priv_cmd_q;
1119 struct priv_cmd_entry *e; 1119 u32 size;
1120 u32 i = 0, size;
1121 int err = 0; 1120 int err = 0;
1122 1121
1123 /* Kernel can insert gpfifos before and after user gpfifos. 1122 /* Kernel can insert gpfifos before and after user gpfifos.
@@ -1143,19 +1142,6 @@ static int channel_gk20a_alloc_priv_cmdbuf(struct channel_gk20a *c)
1143 INIT_LIST_HEAD(&q->head); 1142 INIT_LIST_HEAD(&q->head);
1144 INIT_LIST_HEAD(&q->free); 1143 INIT_LIST_HEAD(&q->free);
1145 1144
1146 /* pre-alloc 25% of priv cmdbuf entries and put them on free list */
1147 for (i = 0; i < q->size / 4; i++) {
1148 e = kzalloc(sizeof(struct priv_cmd_entry), GFP_KERNEL);
1149 if (!e) {
1150 gk20a_err(d, "ch %d: fail to pre-alloc cmd entry",
1151 c->hw_chid);
1152 err = -ENOMEM;
1153 goto clean_up;
1154 }
1155 e->pre_alloc = true;
1156 list_add(&e->list, &q->free);
1157 }
1158
1159 return 0; 1145 return 0;
1160 1146
1161clean_up: 1147clean_up:
@@ -1186,8 +1172,7 @@ static void channel_gk20a_free_priv_cmdbuf(struct channel_gk20a *c)
1186 head = &q->free; 1172 head = &q->free;
1187 list_for_each_safe(pos, tmp, head) { 1173 list_for_each_safe(pos, tmp, head) {
1188 e = container_of(pos, struct priv_cmd_entry, list); 1174 e = container_of(pos, struct priv_cmd_entry, list);
1189 e->pre_alloc = false; 1175 kfree(e);
1190 free_priv_cmdbuf(c, e);
1191 } 1176 }
1192 1177
1193 memset(q, 0, sizeof(struct priv_cmd_queue)); 1178 memset(q, 0, sizeof(struct priv_cmd_queue));
@@ -1199,7 +1184,6 @@ int gk20a_channel_alloc_priv_cmdbuf(struct channel_gk20a *c, u32 orig_size,
1199{ 1184{
1200 struct priv_cmd_queue *q = &c->priv_cmd_q; 1185 struct priv_cmd_queue *q = &c->priv_cmd_q;
1201 struct priv_cmd_entry *e; 1186 struct priv_cmd_entry *e;
1202 struct list_head *node;
1203 u32 free_count; 1187 u32 free_count;
1204 u32 size = orig_size; 1188 u32 size = orig_size;
1205 bool no_retry = false; 1189 bool no_retry = false;
@@ -1228,22 +1212,12 @@ TRY_AGAIN:
1228 return -EAGAIN; 1212 return -EAGAIN;
1229 } 1213 }
1230 1214
1231 if (unlikely(list_empty(&q->free))) { 1215 e = kzalloc(sizeof(struct priv_cmd_entry), GFP_KERNEL);
1232 1216 if (!e) {
1233 gk20a_dbg_info("ch %d: run out of pre-alloc entries", 1217 gk20a_err(dev_from_gk20a(c->g),
1218 "ch %d: fail to allocate priv cmd entry",
1234 c->hw_chid); 1219 c->hw_chid);
1235 1220 return -ENOMEM;
1236 e = kzalloc(sizeof(struct priv_cmd_entry), GFP_KERNEL);
1237 if (!e) {
1238 gk20a_err(dev_from_gk20a(c->g),
1239 "ch %d: fail to allocate priv cmd entry",
1240 c->hw_chid);
1241 return -ENOMEM;
1242 }
1243 } else {
1244 node = q->free.next;
1245 list_del(node);
1246 e = container_of(node, struct priv_cmd_entry, list);
1247 } 1221 }
1248 1222
1249 e->size = orig_size; 1223 e->size = orig_size;
@@ -1281,20 +1255,12 @@ TRY_AGAIN:
1281static void free_priv_cmdbuf(struct channel_gk20a *c, 1255static void free_priv_cmdbuf(struct channel_gk20a *c,
1282 struct priv_cmd_entry *e) 1256 struct priv_cmd_entry *e)
1283{ 1257{
1284 struct priv_cmd_queue *q = &c->priv_cmd_q;
1285
1286 if (!e) 1258 if (!e)
1287 return; 1259 return;
1288 1260
1289 list_del(&e->list); 1261 list_del(&e->list);
1290 1262
1291 if (unlikely(!e->pre_alloc)) 1263 kfree(e);
1292 kfree(e);
1293 else {
1294 memset(e, 0, sizeof(struct priv_cmd_entry));
1295 e->pre_alloc = true;
1296 list_add(&e->list, &q->free);
1297 }
1298} 1264}
1299 1265
1300/* free entries if they're no longer being used */ 1266/* free entries if they're no longer being used */
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
index 47ebd2a1..231f7c9a 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
@@ -168,7 +168,6 @@ struct priv_cmd_entry {
168 u32 gp_get; /* gp_get when submitting last priv cmd */ 168 u32 gp_get; /* gp_get when submitting last priv cmd */
169 u32 gp_put; /* gp_put when submitting last priv cmd */ 169 u32 gp_put; /* gp_put when submitting last priv cmd */
170 u32 gp_wrap; /* wrap when submitting last priv cmd */ 170 u32 gp_wrap; /* wrap when submitting last priv cmd */
171 bool pre_alloc; /* prealloc entry, free to free list */
172 struct list_head list; /* node for lists */ 171 struct list_head list; /* node for lists */
173}; 172};
174 173