Merge tag 'dt-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / drivers / dma-buf / dma-buf.c
index 511fe0d..63d3226 100644 (file)
@@ -29,6 +29,8 @@
 #include <uapi/linux/dma-buf.h>
 #include <uapi/linux/magic.h>
 
+#include "dma-buf-sysfs-stats.h"
+
 static inline int is_dma_buf_file(struct file *);
 
 struct dma_buf_list {
@@ -74,6 +76,7 @@ static void dma_buf_release(struct dentry *dentry)
         */
        BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
 
+       dma_buf_stats_teardown(dmabuf);
        dmabuf->ops->release(dmabuf);
 
        if (dmabuf->resv == (struct dma_resv *)&dmabuf[1])
@@ -580,6 +583,10 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
        file->f_mode |= FMODE_LSEEK;
        dmabuf->file = file;
 
+       ret = dma_buf_stats_setup(dmabuf);
+       if (ret)
+               goto err_sysfs;
+
        mutex_init(&dmabuf->lock);
        INIT_LIST_HEAD(&dmabuf->attachments);
 
@@ -589,6 +596,14 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
 
        return dmabuf;
 
+err_sysfs:
+       /*
+        * Set file->f_path.dentry->d_fsdata to NULL so that when
+        * dma_buf_release() gets invoked by dentry_ops, it exits
+        * early before calling the release() dma_buf op.
+        */
+       file->f_path.dentry->d_fsdata = NULL;
+       fput(file);
 err_dmabuf:
        kfree(dmabuf);
 err_module:
@@ -926,6 +941,9 @@ EXPORT_SYMBOL_GPL(dma_buf_unpin);
  * the underlying backing storage is pinned for as long as a mapping exists,
  * therefore users/importers should not hold onto a mapping for undue amounts of
  * time.
+ *
+ * Important: Dynamic importers must wait for the exclusive fence of the struct
+ * dma_resv attached to the DMA-BUF first.
  */
 struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
                                        enum dma_data_direction direction)
@@ -992,7 +1010,6 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
                }
        }
 #endif /* CONFIG_DMA_API_DEBUG */
-
        return sg_table;
 }
 EXPORT_SYMBOL_GPL(dma_buf_map_attachment);
@@ -1469,6 +1486,12 @@ static inline void dma_buf_uninit_debugfs(void)
 
 static int __init dma_buf_init(void)
 {
+       int ret;
+
+       ret = dma_buf_init_sysfs_statistics();
+       if (ret)
+               return ret;
+
        dma_buf_mnt = kern_mount(&dma_buf_fs_type);
        if (IS_ERR(dma_buf_mnt))
                return PTR_ERR(dma_buf_mnt);
@@ -1484,5 +1507,6 @@ static void __exit dma_buf_deinit(void)
 {
        dma_buf_uninit_debugfs();
        kern_unmount(dma_buf_mnt);
+       dma_buf_uninit_sysfs_statistics();
 }
 __exitcall(dma_buf_deinit);