{
const size_t wqi_size = sizeof(struct guc_wq_item);
struct i915_guc_client *gc = request->i915->guc.execbuf_client;
- struct guc_process_desc *desc;
+ struct guc_process_desc *desc = gc->client_base + gc->proc_desc_offset;
u32 freespace;
+ int ret;
- GEM_BUG_ON(gc == NULL);
-
- desc = gc->client_base + gc->proc_desc_offset;
-
+ spin_lock(&gc->wq_lock);
freespace = CIRC_SPACE(gc->wq_tail, desc->head, gc->wq_size);
- if (likely(freespace >= wqi_size))
- return 0;
-
- gc->no_wq_space += 1;
+ freespace -= gc->wq_rsvd;
+ if (likely(freespace >= wqi_size)) {
+ gc->wq_rsvd += wqi_size;
+ ret = 0;
+ } else {
+ gc->no_wq_space++;
+ ret = -EAGAIN;
+ }
+ spin_unlock(&gc->wq_lock);
- return -EAGAIN;
+ return ret;
}
static void guc_add_workqueue_item(struct i915_guc_client *gc,
* workqueue buffer dw by dw.
*/
BUILD_BUG_ON(wqi_size != 16);
+ GEM_BUG_ON(gc->wq_rsvd < wqi_size);
/* postincrement WQ tail for next time */
wq_off = gc->wq_tail;
+ GEM_BUG_ON(wq_off & (wqi_size - 1));
gc->wq_tail += wqi_size;
gc->wq_tail &= gc->wq_size - 1;
- GEM_BUG_ON(wq_off & (wqi_size - 1));
+ gc->wq_rsvd -= wqi_size;
/* WQ starts from the page after doorbell / process_desc */
wq_page = (wq_off + GUC_DB_SIZE) >> PAGE_SHIFT;
struct i915_guc_client *client = guc->execbuf_client;
int b_ret;
+ spin_lock(&client->wq_lock);
guc_add_workqueue_item(client, rq);
b_ret = guc_ring_doorbell(client);
guc->submissions[engine_id] += 1;
guc->last_seqno[engine_id] = rq->fence.seqno;
+ spin_unlock(&client->wq_lock);
}
/*
/* We'll keep just the first (doorbell/proc) page permanently kmap'd. */
client->vma = vma;
client->client_base = kmap(i915_vma_first_page(vma));
+
+ spin_lock_init(&client->wq_lock);
client->wq_offset = GUC_DB_SIZE;
client->wq_size = GUC_WQ_SIZE;
engine->submit_request = i915_guc_submit;
/* Replay the current set of previously submitted requests */
- list_for_each_entry(request, &engine->request_list, link)
+ list_for_each_entry(request, &engine->request_list, link) {
+ client->wq_rsvd += sizeof(struct guc_wq_item);
if (i915_sw_fence_done(&request->submit))
i915_guc_submit(request);
+ }
}
return 0;