Skip to contentSkip to conversation

usb: gadget: f_fs: Remove deprecated dma_fence->ops

PATCH In review Philipp Stanner 5 participants 7 messages Oct 29 – Oct 30

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 usb: gadget: f_fs: Remove deprecated dma_fence->ops

The dma_fence_ops function ops->release() has been deprecated because it prevents drivers from unloading. f_fs's implementation merely frees the fence. The dma_fence backend performs this deallocation automatically in the correct manner if ops->release() is not implemented.

The backend simultaneously correctly frees struct ffs_dma_fence since struct dma_fence is its base class.

Remove ops->release().

---
 drivers/usb/gadget/function/f_fs.c | 9 ---------
 1 file changed, 9 deletions(-)
drivers/usb/gadget/function/f_fs.c +0 -9
index c64a268e98a4..e8672b37e890 100644
@@ -1479,18 +1479,9 @@ static const char *ffs_dmabuf_get_timeline_name(struct dma_fence *fence)
 	return "";
 }
 
-static void ffs_dmabuf_fence_release(struct dma_fence *fence)
-{
-	struct ffs_dma_fence *dma_fence =
-		container_of(fence, struct ffs_dma_fence, base);
-
-	kfree(dma_fence);
-}
-
 static const struct dma_fence_ops ffs_dmabuf_fence_ops = {
 	.get_driver_name	= ffs_dmabuf_get_driver_name,
 	.get_timeline_name	= ffs_dmabuf_get_timeline_name,
-	.release		= ffs_dmabuf_fence_release,
 };
 
 static int ffs_dma_resv_lock(struct dma_buf *dmabuf, bool nonblock)
Signature · 1 line
2.56.0
#1 lore raw
Sashiko has reviewed this patch and found no issues.
Quoted 11 lines

The dma_fence_ops function ops->release() has been deprecated because it prevents drivers from unloading. f_fs's implementation merely frees the fence. The dma_fence backend performs this deallocation automatically in the correct manner if ops->release() is not implemented.

The backend simultaneously correctly frees struct ffs_dma_fence since struct dma_fence is its base class.

Remove ops->release().

Sashiko has reviewed this patch and found no issues.

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
#2 lore raw
In reply to Philipp Stanner

Hi Philipp,

Le jeudi 29 octobre 2026 à 13:51 +0100, Philipp Stanner a écrit :

Quoted 7 lines

The dma_fence_ops function ops->release() has been deprecated because it prevents drivers from unloading. f_fs's implementation merely frees the fence. The dma_fence backend performs this deallocation automatically in the correct manner if ops->release() is not implemented.

The backend simultaneously correctly frees struct ffs_dma_fence since struct dma_fence is its base class.

For context, this .release() callback was added to avoid the implicit free of the base class, which IIRC was a request I got during the review process of this change set.

I'm personally fine with the change, but do we need a "keep this field at the top" comment for the base class in the ffs_dma_fence struct? Or what's the policy here?

Cheers,
-Paul

Quoted 33 lines

Remove ops->release().

---
 drivers/usb/gadget/function/f_fs.c | 9 ---------

 1 file changed, 9 deletions(-)
drivers/usb/gadget/function/f_fs.c +0 -0
index c64a268e98a4..e8672b37e890 100644
@@ -1479,18 +1479,9 @@ static const char *ffs_dmabuf_get_timeline_name(struct
 dma_fence *fence)
  	return "";
  }

drivers/usb/gadget/function/f_fs.c +0 -8
-static void ffs_dmabuf_fence_release(struct dma_fence *fence)
-{
-	struct ffs_dma_fence *dma_fence =
-		container_of(fence, struct ffs_dma_fence, base);
-
-	kfree(dma_fence);
-}
-

 static const struct dma_fence_ops ffs_dmabuf_fence_ops = {
  .get_driver_name = ffs_dmabuf_get_driver_name,
  .get_timeline_name = ffs_dmabuf_get_timeline_name,

drivers/usb/gadget/function/f_fs.c +0 -1
-	.release		= ffs_dmabuf_fence_release,

 };

 static int ffs_dma_resv_lock(struct dma_buf *dmabuf, bool nonblock)

#3 lore raw

Hi,

Quoted 5 lines · Paul Cercueil

Hi Philipp,

For context, this .release() callback was added to avoid the implicit free of the base class, which IIRC was a request I got during the review process of this change set.

Can't say anything about the request you got, but fences are reference- counted and the ability to free itself exists since at least 3c3b177a9369 (2014).

From dma_fence's perspective it's certainly the desired canonical pattern since the release() ops prevents fences from the important feature of decoupling fence producer and consumer.

Quoted 4 lines

I'm personally fine with the change, but do we need a "keep this field at the top" comment for the base class in the ffs_dma_fence struct? Or what's the policy here?

When I got into the kernel I was told that it's common practice to always have the base class as the first element. That also allows for obtaining the parent class by a mere pointer-cast instead of container_of.

But the reality is also that some users are not aware of this rule. I can document it in a v2 if you like.

Regards,
Philipp

#4 lore raw

Le jeudi 29 octobre 2026 à 14:49 +0100, Philipp Stanner a écrit :

Quoted 11 lines

Hi,

Quoted 7 lines · Paul Cercueil

Hi Philipp,

For context, this .release() callback was added to avoid the implicit free of
the base class, which IIRC was a request I got during the review process of this
change set.

Quoted 3 lines

Can't say anything about the request you got, but fences are reference- counted and the ability to free itself exists since at least 3c3b177a9369 (2014).

Yes, it already existed when I wrote the code and I was requested to make it explicit. Not trying to make a point here, just stating the reasons why it was written that way.

Quoted 3 lines

From dma_fence's perspective it's certainly the desired canonical pattern since the release() ops prevents fences from the important feature of decoupling fence producer and consumer.

ACK.

Quoted 5 lines
Quoted 4 lines

I'm personally fine with the change, but do we need a "keep this field at the
top" comment for the base class in the ffs_dma_fence struct? Or what's the policy here?

Quoted 7 lines

When I got into the kernel I was told that it's common practice to always have the base class as the first element. That also allows for obtaining the parent class by a mere pointer-cast instead of container_of.

But the reality is also that some users are not aware of this rule. I can document it in a v2 if you like.

Let's wait on feedback from more people. I don't have a strong opinion either way.

Cheers,
-Paul

#5 lore raw
Quoted 36 lines · Paul Cercueil

Le jeudi 29 octobre 2026 à 14:49 +0100, Philipp Stanner a écrit :

Quoted 11 lines

Hi,

Quoted 7 lines · Paul Cercueil

Hi Philipp,

For context, this .release() callback was added to avoid the implicit free of
the base class, which IIRC was a request I got during the review process of this
change set.

Quoted 3 lines

Can't say anything about the request you got, but fences are reference- counted and the ability to free itself exists since at least 3c3b177a9369 (2014).

Yes, it already existed when I wrote the code and I was requested to make it explicit. Not trying to make a point here, just stating the reasons why it was written that way.

Quoted 3 lines

From dma_fence's perspective it's certainly the desired canonical pattern since the release() ops prevents fences from the important feature of decoupling fence producer and consumer.

ACK.

Quoted 10 lines
Quoted 4 lines

I'm personally fine with the change, but do we need a "keep this field at the
top" comment for the base class in the ffs_dma_fence struct? Or what's the policy here?

When I got into the kernel I was told that it's common practice to always have the base class as the first element. That also allows for obtaining the parent class by a mere pointer-cast instead of container_of.

Quoted 5 lines
Quoted 2 lines

But the reality is also that some users are not aware of this rule. I can document it in a v2 if you like.

Let's wait on feedback from more people. I don't have a strong opinion either way.

As far as I know It is indeed common practice , if you want a comment or not on your structure that the base class needs to be the first element or the dma_fence release will break is totally up to you I think.

On the other hand it is maybe possible to provide a dma_fence_alloc_obj() macro which wraps kmalloc_obj and compile time asserts that the member you give for the base class is at offset 0.

Regards,
Christian.

Quoted 3 lines

Cheers,
-Paul

Reviewed-by on v1 1/1
#6 lore raw
In reply to Philipp Stanner
Quoted 11 lines · Philipp Stanner

The dma_fence_ops function ops->release() has been deprecated because it prevents drivers from unloading. f_fs's implementation merely frees the fence. The dma_fence backend performs this deallocation automatically in the correct manner if ops->release() is not implemented.

The backend simultaneously correctly frees struct ffs_dma_fence since struct dma_fence is its base class.

Remove ops->release().

Quoted 27 lines
---
 drivers/usb/gadget/function/f_fs.c | 9 ---------
 1 file changed, 9 deletions(-)
drivers/usb/gadget/function/f_fs.c +0 -9
index c64a268e98a4..e8672b37e890 100644
@@ -1479,18 +1479,9 @@ static const char *ffs_dmabuf_get_timeline_name(struct dma_fence *fence)
 	return "";
 }
 
-static void ffs_dmabuf_fence_release(struct dma_fence *fence)
-{
-	struct ffs_dma_fence *dma_fence =
-		container_of(fence, struct ffs_dma_fence, base);
-
-	kfree(dma_fence);
-}
-
 static const struct dma_fence_ops ffs_dmabuf_fence_ops = {
 	.get_driver_name	= ffs_dmabuf_get_driver_name,
 	.get_timeline_name	= ffs_dmabuf_get_timeline_name,
-	.release		= ffs_dmabuf_fence_release,
 };
 
 static int ffs_dma_resv_lock(struct dma_buf *dmabuf, bool nonblock)