Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpu: host1x: Remove mid-job CDMA flushes

The current code can issue CDMA flushes (DMAPUT bumps) in the middle
of a job, before all opcodes have been written into the pushbuffer.
This can happen when pushbuffer fills up. Presumably this made sense
at some point in the past, but it doesn't anymore, as it cannot lead
to more space appearing in the pushbuffer as it is only cleaned full
jobs at a time.

Mid-job flushes can also cause problems, as in an extreme situation
(seen in practice), the hardware can run through the entire pushbuffer
including the prefix of a partially written job without the driver
being able to process any CDMA updates. This can cause the engine
MLOCK to be taken and held for extended periods as the tail of the
job is not yet available to hardware.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Link: https://lore.kernel.org/r/20250204024546.1168126-1-mperttunen@nvidia.com

authored by

Mikko Perttunen and committed by
Thierry Reding
33ca5aaf 408ec8e4

+1 -6
+1 -6
drivers/gpu/host1x/cdma.c
··· 247 247 trace_host1x_wait_cdma(dev_name(cdma_to_channel(cdma)->dev), 248 248 CDMA_EVENT_PUSH_BUFFER_SPACE); 249 249 250 - host1x_hw_cdma_flush(host1x, cdma); 251 - 252 250 /* If somebody has managed to already start waiting, yield */ 253 251 if (cdma->event != CDMA_EVENT_NONE) { 254 252 mutex_unlock(&cdma->lock); ··· 589 591 */ 590 592 void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, u32 op2) 591 593 { 592 - struct host1x *host1x = cdma_to_host1x(cdma); 593 594 struct push_buffer *pb = &cdma->push_buffer; 594 595 u32 slots_free = cdma->slots_free; 595 596 ··· 596 599 trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev), 597 600 op1, op2); 598 601 599 - if (slots_free == 0) { 600 - host1x_hw_cdma_flush(host1x, cdma); 602 + if (slots_free == 0) 601 603 slots_free = host1x_cdma_wait_locked(cdma, 602 604 CDMA_EVENT_PUSH_BUFFER_SPACE); 603 - } 604 605 605 606 cdma->slots_free = slots_free - 1; 606 607 cdma->slots_used++;