{
        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;