Skip to content

Commit 6d3d827

Browse files
Nick Hoathdanvet
authored andcommitted
drm/i915: Subsume intel_ctx_submit_request in to drm_i915_gem_request
Move all remaining elements that were unique to execlists queue items in to the associated request. Issue: VIZ-4274 v2: Rebase. Fixed issue of overzealous freeing of request. v3: Removed re-addition of cleanup work queue (found by Daniel Vetter) v4: Rebase. v5: Actual removal of intel_ctx_submit_request. Update both tail and postfix pointer in __i915_add_request (found by Thomas Daniel) v6: Removed unrelated changes Signed-off-by: Nick Hoath <[email protected]> Reviewed-by: Thomas Daniel <[email protected]> [danvet: Reformat comment with strange linebreaks.] Signed-off-by: Daniel Vetter <[email protected]>
1 parent 2107637 commit 6d3d827

File tree

5 files changed

+49
-62
lines changed

5 files changed

+49
-62
lines changed

drivers/gpu/drm/i915/i915_debugfs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,7 +1928,7 @@ static int i915_execlists(struct seq_file *m, void *data)
19281928
intel_runtime_pm_get(dev_priv);
19291929

19301930
for_each_ring(ring, dev_priv, ring_id) {
1931-
struct intel_ctx_submit_request *head_req = NULL;
1931+
struct drm_i915_gem_request *head_req = NULL;
19321932
int count = 0;
19331933
unsigned long flags;
19341934

@@ -1961,18 +1961,18 @@ static int i915_execlists(struct seq_file *m, void *data)
19611961
list_for_each(cursor, &ring->execlist_queue)
19621962
count++;
19631963
head_req = list_first_entry_or_null(&ring->execlist_queue,
1964-
struct intel_ctx_submit_request, execlist_link);
1964+
struct drm_i915_gem_request, execlist_link);
19651965
spin_unlock_irqrestore(&ring->execlist_lock, flags);
19661966

19671967
seq_printf(m, "\t%d requests in queue\n", count);
19681968
if (head_req) {
19691969
struct drm_i915_gem_object *ctx_obj;
19701970

1971-
ctx_obj = head_req->request->ctx->engine[ring_id].state;
1971+
ctx_obj = head_req->ctx->engine[ring_id].state;
19721972
seq_printf(m, "\tHead request id: %u\n",
19731973
intel_execlists_ctx_id(ctx_obj));
19741974
seq_printf(m, "\tHead request tail: %u\n",
1975-
head_req->request->tail);
1975+
head_req->tail);
19761976
}
19771977

19781978
seq_putc(m, '\n');

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,6 +2116,26 @@ struct drm_i915_gem_request {
21162116
struct list_head client_list;
21172117

21182118
uint32_t uniq;
2119+
2120+
/**
2121+
* The ELSP only accepts two elements at a time, so we queue
2122+
* context/tail pairs on a given queue (ring->execlist_queue) until the
2123+
* hardware is available. The queue serves a double purpose: we also use
2124+
* it to keep track of the up to 2 contexts currently in the hardware
2125+
* (usually one in execution and the other queued up by the GPU): We
2126+
* only remove elements from the head of the queue when the hardware
2127+
* informs us that an element has been completed.
2128+
*
2129+
* All accesses to the queue are mediated by a spinlock
2130+
* (ring->execlist_lock).
2131+
*/
2132+
2133+
/** Execlist link in the submission queue.*/
2134+
struct list_head execlist_link;
2135+
2136+
/** Execlists no. of times this request has been sent to the ELSP */
2137+
int elsp_submitted;
2138+
21192139
};
21202140

21212141
void i915_gem_request_free(struct kref *req_ref);

drivers/gpu/drm/i915/i915_gem.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2414,7 +2414,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
24142414
struct drm_i915_private *dev_priv = ring->dev->dev_private;
24152415
struct drm_i915_gem_request *request;
24162416
struct intel_ringbuffer *ringbuf;
2417-
u32 request_ring_position, request_start;
2417+
u32 request_start;
24182418
int ret;
24192419

24202420
request = ring->outstanding_lazy_request;
@@ -2449,7 +2449,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
24492449
* GPU processing the request, we never over-estimate the
24502450
* position of the head.
24512451
*/
2452-
request_ring_position = intel_ring_get_tail(ringbuf);
2452+
request->postfix = intel_ring_get_tail(ringbuf);
24532453

24542454
if (i915.enable_execlists) {
24552455
ret = ring->emit_request(ringbuf, request);
@@ -2462,7 +2462,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
24622462
}
24632463

24642464
request->head = request_start;
2465-
request->postfix = request_ring_position;
2465+
request->tail = intel_ring_get_tail(ringbuf);
24662466

24672467
/* Whilst this request exists, batch_obj will be on the
24682468
* active_list, and so will hold the active reference. Only when this
@@ -2649,14 +2649,14 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv,
26492649
* pinned in place.
26502650
*/
26512651
while (!list_empty(&ring->execlist_queue)) {
2652-
struct intel_ctx_submit_request *submit_req;
2652+
struct drm_i915_gem_request *submit_req;
26532653

26542654
submit_req = list_first_entry(&ring->execlist_queue,
2655-
struct intel_ctx_submit_request,
2655+
struct drm_i915_gem_request,
26562656
execlist_link);
26572657
list_del(&submit_req->execlist_link);
26582658
intel_runtime_pm_put(dev_priv);
2659-
i915_gem_context_unreference(submit_req->request->ctx);
2659+
i915_gem_context_unreference(submit_req->ctx);
26602660
kfree(submit_req);
26612661
}
26622662

drivers/gpu/drm/i915/intel_lrc.c

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,8 @@ static void execlists_submit_contexts(struct intel_engine_cs *ring,
404404

405405
static void execlists_context_unqueue(struct intel_engine_cs *ring)
406406
{
407-
struct intel_ctx_submit_request *req0 = NULL, *req1 = NULL;
408-
struct intel_ctx_submit_request *cursor = NULL, *tmp = NULL;
407+
struct drm_i915_gem_request *req0 = NULL, *req1 = NULL;
408+
struct drm_i915_gem_request *cursor = NULL, *tmp = NULL;
409409

410410
assert_spin_locked(&ring->execlist_lock);
411411

@@ -417,7 +417,7 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
417417
execlist_link) {
418418
if (!req0) {
419419
req0 = cursor;
420-
} else if (req0->request->ctx == cursor->request->ctx) {
420+
} else if (req0->ctx == cursor->ctx) {
421421
/* Same ctx: ignore first request, as second request
422422
* will update tail past first request's workload */
423423
cursor->elsp_submitted = req0->elsp_submitted;
@@ -433,9 +433,9 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
433433

434434
WARN_ON(req1 && req1->elsp_submitted);
435435

436-
execlists_submit_contexts(ring, req0->request->ctx, req0->request->tail,
437-
req1 ? req1->request->ctx : NULL,
438-
req1 ? req1->request->tail : 0);
436+
execlists_submit_contexts(ring, req0->ctx, req0->tail,
437+
req1 ? req1->ctx : NULL,
438+
req1 ? req1->tail : 0);
439439

440440
req0->elsp_submitted++;
441441
if (req1)
@@ -445,17 +445,17 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
445445
static bool execlists_check_remove_request(struct intel_engine_cs *ring,
446446
u32 request_id)
447447
{
448-
struct intel_ctx_submit_request *head_req;
448+
struct drm_i915_gem_request *head_req;
449449

450450
assert_spin_locked(&ring->execlist_lock);
451451

452452
head_req = list_first_entry_or_null(&ring->execlist_queue,
453-
struct intel_ctx_submit_request,
453+
struct drm_i915_gem_request,
454454
execlist_link);
455455

456456
if (head_req != NULL) {
457457
struct drm_i915_gem_object *ctx_obj =
458-
head_req->request->ctx->engine[ring->id].state;
458+
head_req->ctx->engine[ring->id].state;
459459
if (intel_execlists_ctx_id(ctx_obj) == request_id) {
460460
WARN(head_req->elsp_submitted == 0,
461461
"Never submitted head request\n");
@@ -537,15 +537,11 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
537537
u32 tail,
538538
struct drm_i915_gem_request *request)
539539
{
540-
struct intel_ctx_submit_request *req = NULL, *cursor;
540+
struct drm_i915_gem_request *cursor;
541541
struct drm_i915_private *dev_priv = ring->dev->dev_private;
542542
unsigned long flags;
543543
int num_elements = 0;
544544

545-
req = kzalloc(sizeof(*req), GFP_KERNEL);
546-
if (req == NULL)
547-
return -ENOMEM;
548-
549545
if (to != ring->default_context)
550546
intel_lr_context_pin(ring, to);
551547

@@ -559,14 +555,13 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
559555
if (request == NULL)
560556
return -ENOMEM;
561557
request->ring = ring;
558+
request->ctx = to;
562559
} else {
563560
WARN_ON(to != request->ctx);
564561
}
565-
request->ctx = to;
566562
request->tail = tail;
567-
req->request = request;
568563
i915_gem_request_reference(request);
569-
i915_gem_context_reference(req->request->ctx);
564+
i915_gem_context_reference(request->ctx);
570565

571566
intel_runtime_pm_get(dev_priv);
572567

@@ -577,13 +572,13 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
577572
break;
578573

579574
if (num_elements > 2) {
580-
struct intel_ctx_submit_request *tail_req;
575+
struct drm_i915_gem_request *tail_req;
581576

582577
tail_req = list_last_entry(&ring->execlist_queue,
583-
struct intel_ctx_submit_request,
578+
struct drm_i915_gem_request,
584579
execlist_link);
585580

586-
if (to == tail_req->request->ctx) {
581+
if (to == tail_req->ctx) {
587582
WARN(tail_req->elsp_submitted != 0,
588583
"More than 2 already-submitted reqs queued\n");
589584
list_del(&tail_req->execlist_link);
@@ -592,7 +587,7 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
592587
}
593588
}
594589

595-
list_add_tail(&req->execlist_link, &ring->execlist_queue);
590+
list_add_tail(&request->execlist_link, &ring->execlist_queue);
596591
if (num_elements == 0)
597592
execlists_context_unqueue(ring);
598593

@@ -761,7 +756,7 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
761756

762757
void intel_execlists_retire_requests(struct intel_engine_cs *ring)
763758
{
764-
struct intel_ctx_submit_request *req, *tmp;
759+
struct drm_i915_gem_request *req, *tmp;
765760
struct drm_i915_private *dev_priv = ring->dev->dev_private;
766761
unsigned long flags;
767762
struct list_head retired_list;
@@ -776,17 +771,16 @@ void intel_execlists_retire_requests(struct intel_engine_cs *ring)
776771
spin_unlock_irqrestore(&ring->execlist_lock, flags);
777772

778773
list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) {
779-
struct intel_context *ctx = req->request->ctx;
774+
struct intel_context *ctx = req->ctx;
780775
struct drm_i915_gem_object *ctx_obj =
781776
ctx->engine[ring->id].state;
782777

783778
if (ctx_obj && (ctx != ring->default_context))
784779
intel_lr_context_unpin(ring, ctx);
785780
intel_runtime_pm_put(dev_priv);
786781
i915_gem_context_unreference(ctx);
787-
i915_gem_request_unreference(req->request);
782+
i915_gem_request_unreference(req);
788783
list_del(&req->execlist_link);
789-
kfree(req);
790784
}
791785
}
792786

drivers/gpu/drm/i915/intel_lrc.h

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -89,33 +89,6 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
8989
u64 exec_start, u32 flags);
9090
u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj);
9191

92-
/**
93-
* struct intel_ctx_submit_request - queued context submission request
94-
* @ctx: Context to submit to the ELSP.
95-
* @ring: Engine to submit it to.
96-
* @tail: how far in the context's ringbuffer this request goes to.
97-
* @execlist_link: link in the submission queue.
98-
* @work: workqueue for processing this request in a bottom half.
99-
* @elsp_submitted: no. of times this request has been sent to the ELSP.
100-
*
101-
* The ELSP only accepts two elements at a time, so we queue context/tail
102-
* pairs on a given queue (ring->execlist_queue) until the hardware is
103-
* available. The queue serves a double purpose: we also use it to keep track
104-
* of the up to 2 contexts currently in the hardware (usually one in execution
105-
* and the other queued up by the GPU): We only remove elements from the head
106-
* of the queue when the hardware informs us that an element has been
107-
* completed.
108-
*
109-
* All accesses to the queue are mediated by a spinlock (ring->execlist_lock).
110-
*/
111-
struct intel_ctx_submit_request {
112-
struct list_head execlist_link;
113-
114-
int elsp_submitted;
115-
116-
struct drm_i915_gem_request *request;
117-
};
118-
11992
void intel_lrc_irq_handler(struct intel_engine_cs *ring);
12093
void intel_execlists_retire_requests(struct intel_engine_cs *ring);
12194

0 commit comments

Comments
 (0)