dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Slaby <jirislaby@kernel.org>
To: phasta@kernel.org,
	"Christian König" <ckoenig.leichtzumerken@gmail.com>,
	tursulin@ursulin.net, matthew.brost@intel.com,
	sumit.semwal@linaro.org
Cc: dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org
Subject: Re: [PATCH 1/9] dma-buf: add dma_fence_was_initialized function v2
Date: Fri, 28 Aug 2026 09:46:18 +0200	[thread overview]
Message-ID: <f8b941a8-a468-4243-836e-aa6cebf6f3b3@kernel.org> (raw)
In-Reply-To: <0df59c80-ae58-47d3-a96b-e878a17766a7@kernel.org>

On 28. 08. 26, 9:29, Jiri Slaby wrote:
> On 19. 08. 26, 14:51, Philipp Stanner wrote:
>> On Wed, 2026-08-19 at 14:33 +0200, Philipp Stanner wrote:
>>
>>
>> […]
>>
>>>
>>> Regardless, looking at the code again, I would say that this might be a
>>> race, but I don't know enough about QXL to say for sure.
>>>
>>> dma_fence_init() is (of course) not ordered:
>>>
>>>
>>> static void
>>> __dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops 
>>> *ops,
>>>              spinlock_t *lock, u64 context, u64 seqno, unsigned long 
>>> flags)
>>> {
>>>     BUG_ON(!ops || !ops->get_driver_name || !ops->get_timeline_name);
>>>
>>>     kref_init(&fence->refcount);
>>>     /*
>>>      * While it is counter intuitive to protect a constant function 
>>> pointer
>>>      * table by RCU it allows modules to wait for an RCU grace period
>>>      * before they unload, to make sure that nobody is executing their
>>>      * functions any more.
>>>      */
>>>     RCU_INIT_POINTER(fence->ops, ops);
>>>     INIT_LIST_HEAD(&fence->cb_list);
>>>     fence->context = context;
>>>     fence->seqno = seqno;
>>>     fence->flags = flags | BIT(DMA_FENCE_FLAG_INITIALIZED_BIT);
>>>
>>> (Should this maybe be set_bit() btw?)
>>>
>>>
>>> The fact that QXL could run into qxl_release_free() with an
>>> uninitialized fence hints at the fact that this might race, so
>>> DMA_FENCE_FLAG_INITIALIZED_BIT could be set / read before kref_init()
>>> ran.
>>>
>>>
>>> Maybe one way to verify / debug that would be to move
>>> spin_unlock(&qdev->release_idr_lock) downwards so it also guards
>>> dma_fence_was_initialized(), and also lock the initialization of the
>>> fence (in qxl_release_fence_buffer_objects() ?) with said lock.
>>>
>>> If that's possible. Just brainstorming a bit for ways how to debug.
>>>
>>> QXL does a few tricky things with the release->base.ops pointer.
>>> qxl_release_alloc() sets it to NULL, and only
>>> qxl_release_fence_buffer_objects() then actually sets it. So this could
>>> be the race? Setting of the ops pointer got replaced by setting of the
>>> fence-flag.
>>>
>>>
>>> P.
>>
>> Could you test something like this? (not even compile-tested, just an 
>> idea)
> 
> It makes the system dead during early boot :P.
> 
>> diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
>> index 87797bea91cb..df1aa48b2809 100644
>> --- a/drivers/dma-buf/dma-fence.c
>> +++ b/drivers/dma-buf/dma-fence.c
>> @@ -1075,7 +1075,6 @@ __dma_fence_init(struct dma_fence *fence, const 
>> struct dma_fence_ops *ops,
>>          INIT_LIST_HEAD(&fence->cb_list);
>>          fence->context = context;
>>          fence->seqno = seqno;
>> -       fence->flags = flags | BIT(DMA_FENCE_FLAG_INITIALIZED_BIT);
>>          if (lock) {
>>                  fence->extern_lock = lock;
>>          } else {
>> @@ -1084,6 +1083,8 @@ __dma_fence_init(struct dma_fence *fence, const 
>> struct dma_fence_ops *ops,
> 
> This missing piece was here:
> -               fence->flags |= BIT(DMA_FENCE_FLAG_INLINE_LOCK_BIT);
> +               flags |= BIT(DMA_FENCE_FLAG_INLINE_LOCK_BIT);
> 
> 
>>          }
>>          fence->error = 0;
>> +       smp_mb();
>> +       fence->flags = flags | BIT(DMA_FENCE_FLAG_INITIALIZED_BIT);
>>          trace_dma_fence_init(fence);
>>   }
> 
> But it does not help either...

What helps is indeed the revert back to:

--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -147,7 +147,7 @@ qxl_release_free(struct qxl_device *qdev,
         idr_remove(&qdev->release_idr, release->id);
         spin_unlock(&qdev->release_idr_lock);

-       if (dma_fence_was_initialized(&release->base)) {
+       if (release->base.ops) {
                 WARN_ON(list_empty(&release->bos));
                 qxl_release_free_list(release);



Or the bool flag appears to help too:

--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -144,6 +144,7 @@ enum {
  #define QXL_MAX_RES 96
  struct qxl_release {
         struct dma_fence base;
+       bool uses_fence;

         int id;
         int type;
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -97,6 +97,7 @@ qxl_release_alloc(struct qxl_device *qdev, int type,
                 return -ENOMEM;
         }
         release->base.ops = NULL;
+       release->uses_fence = false;
         release->type = type;
         release->release_offset = 0;
         release->surface_release_id = 0;
@@ -147,7 +148,7 @@ qxl_release_free(struct qxl_device *qdev,
         idr_remove(&qdev->release_idr, release->id);
         spin_unlock(&qdev->release_idr_lock);

-       if (dma_fence_was_initialized(&release->base)) {
+       if (release->uses_fence) {
                 WARN_ON(list_empty(&release->bos));
                 qxl_release_free_list(release);

@@ -431,6 +432,7 @@ void qxl_release_fence_buffer_objects(struct 
qxl_release *release)
          */
         dma_fence_init(&release->base, &qxl_fence_ops, &qdev->release_lock,
                        release->id | 0xf0000000, release->base.seqno);
+       release->uses_fence = true;
         trace_dma_fence_emit(&release->base);

         list_for_each_entry(entry, &release->bos, list) {


thanks,
-- 
js
suse labs


  reply	other threads:[~2026-08-28  7:46 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-20 10:54 Independence for dma_fences! v6 Christian König
2026-01-20 10:54 ` [PATCH 1/9] dma-buf: add dma_fence_was_initialized function v2 Christian König
2026-01-20 11:33   ` Tvrtko Ursulin
2026-07-13  8:58   ` Jiri Slaby
2026-07-14  7:53     ` Philipp Stanner
2026-07-14  8:43       ` Philipp Stanner
2026-08-19  8:59         ` Jiri Slaby
2026-08-19 12:33           ` Philipp Stanner
2026-08-19 12:51             ` Philipp Stanner
2026-08-28  7:29               ` Jiri Slaby
2026-08-28  7:46                 ` Jiri Slaby [this message]
2026-08-28  8:32                   ` Jiri Slaby
2026-09-02  6:52                     ` Philipp Stanner
2026-09-02  6:56                       ` Jiri Slaby
2026-09-02  7:03                         ` Philipp Stanner
2026-09-02 10:47                           ` Jiri Slaby
2026-01-20 10:54 ` [PATCH 2/9] dma-buf: protected fence ops by RCU v5 Christian König
2026-01-20 10:54 ` [PATCH 3/9] dma-buf: detach fence ops on signal v2 Christian König
2026-01-20 10:54 ` [PATCH 4/9] dma-buf: abstract fence locking Christian König
2026-01-20 10:54 ` [PATCH 5/9] dma-buf: inline spinlock for fence protection v4 Christian König
2026-01-20 11:41   ` Tvrtko Ursulin
2026-01-21  8:48     ` Christian König
2026-01-21  9:03       ` Tvrtko Ursulin
2026-01-27  4:56   ` kernel test robot
2026-01-20 10:54 ` [PATCH 6/9] dma-buf/selftests: test RCU ops and inline lock v2 Christian König
2026-01-20 10:54 ` [PATCH 7/9] dma-buf: use inline lock for the stub fence v2 Christian König
2026-01-21  9:29   ` Philipp Stanner
2026-01-20 10:54 ` [PATCH 8/9] dma-buf: use inline lock for the dma-fence-array Christian König
2026-01-20 10:54 ` [PATCH 9/9] dma-buf: use inline lock for the dma-fence-chain Christian König

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f8b941a8-a468-4243-836e-aa6cebf6f3b3@kernel.org \
    --to=jirislaby@kernel.org \
    --cc=ckoenig.leichtzumerken@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=matthew.brost@intel.com \
    --cc=phasta@kernel.org \
    --cc=sumit.semwal@linaro.org \
    --cc=tursulin@ursulin.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox