diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 50 |
1 files changed, 8 insertions, 42 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 | ||
1161 | clean_up: | 1147 | clean_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: | |||
1281 | static void free_priv_cmdbuf(struct channel_gk20a *c, | 1255 | static 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 */ |