From f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 31 Jan 2024 01:04:47 +0000
Subject: [PATCH] add driver 5G

---
 kernel/include/linux/dma-buf.h |  288 +++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 179 insertions(+), 109 deletions(-)

diff --git a/kernel/include/linux/dma-buf.h b/kernel/include/linux/dma-buf.h
index 4696b11..0b3c064 100644
--- a/kernel/include/linux/dma-buf.h
+++ b/kernel/include/linux/dma-buf.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Header file for dma buffer sharing framework.
  *
@@ -8,18 +9,6 @@
  * Arnd Bergmann <arnd@arndb.de>, Rob Clark <rob@ti.com> and
  * Daniel Vetter <daniel@ffwll.ch> for their support in creation and
  * refining of this idea.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #ifndef __DMA_BUF_H__
 #define __DMA_BUF_H__
@@ -32,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/dma-fence.h>
 #include <linux/wait.h>
+#include <linux/android_kabi.h>
 
 struct device;
 struct dma_buf;
@@ -39,18 +29,20 @@
 
 /**
  * struct dma_buf_ops - operations possible on struct dma_buf
- * @map_atomic: [optional] maps a page from the buffer into kernel address
- *		space, users may not block until the subsequent unmap call.
- *		This callback must not sleep.
- * @unmap_atomic: [optional] unmaps a atomically mapped page from the buffer.
- *		  This Callback must not sleep.
- * @map: [optional] maps a page from the buffer into kernel address space.
- * @unmap: [optional] unmaps a page from the buffer.
  * @vmap: [optional] creates a virtual mapping for the buffer into kernel
  *	  address space. Same restrictions as for vmap and friends apply.
  * @vunmap: [optional] unmaps a vmap from the buffer
  */
 struct dma_buf_ops {
+	/**
+	  * @cache_sgt_mapping:
+	  *
+	  * If true the framework will cache the first mapping made for each
+	  * attachment. This avoids creating mappings for attachments multiple
+	  * times.
+	  */
+	bool cache_sgt_mapping;
+
 	/**
 	 * @attach:
 	 *
@@ -91,13 +83,42 @@
 	void (*detach)(struct dma_buf *, struct dma_buf_attachment *);
 
 	/**
+	 * @pin:
+	 *
+	 * This is called by dma_buf_pin and lets the exporter know that the
+	 * DMA-buf can't be moved any more.
+	 *
+	 * This is called with the dmabuf->resv object locked and is mutual
+	 * exclusive with @cache_sgt_mapping.
+	 *
+	 * This callback is optional and should only be used in limited use
+	 * cases like scanout and not for temporary pin operations.
+	 *
+	 * Returns:
+	 *
+	 * 0 on success, negative error code on failure.
+	 */
+	int (*pin)(struct dma_buf_attachment *attach);
+
+	/**
+	 * @unpin:
+	 *
+	 * This is called by dma_buf_unpin and lets the exporter know that the
+	 * DMA-buf can be moved again.
+	 *
+	 * This is called with the dmabuf->resv object locked and is mutual
+	 * exclusive with @cache_sgt_mapping.
+	 *
+	 * This callback is optional.
+	 */
+	void (*unpin)(struct dma_buf_attachment *attach);
+
+	/**
 	 * @map_dma_buf:
 	 *
 	 * This is called by dma_buf_map_attachment() and is used to map a
 	 * shared &dma_buf into device address space, and it is mandatory. It
-	 * can only be called if @attach has been called successfully. This
-	 * essentially pins the DMA buffer into place, and it cannot be moved
-	 * any more
+	 * can only be called if @attach has been called successfully.
 	 *
 	 * This call may sleep, e.g. when the backing storage first needs to be
 	 * allocated, or moved to a location suitable for all currently attached
@@ -118,6 +139,9 @@
 	 * any other kind of sharing that the exporter might wish to make
 	 * available to buffer-users.
 	 *
+	 * This is always called with the dmabuf->resv object locked when
+	 * the dynamic_mapping flag is true.
+	 *
 	 * Returns:
 	 *
 	 * A &sg_table scatter list of or the backing storage of the DMA buffer,
@@ -135,9 +159,8 @@
 	 *
 	 * This is called by dma_buf_unmap_attachment() and should unmap and
 	 * release the &sg_table allocated in @map_dma_buf, and it is mandatory.
-	 * It should also unpin the backing storage if this is the last mapping
-	 * of the DMA buffer, it the exporter supports backing storage
-	 * migration.
+	 * For static dma_buf handling this might also unpins the backing
+	 * storage if this is the last mapping of the DMA buffer.
 	 */
 	void (*unmap_dma_buf)(struct dma_buf_attachment *,
 			      struct sg_table *,
@@ -146,12 +169,7 @@
 	/* TODO: Add try_map_dma_buf version, to return immed with -EBUSY
 	 * if the call would block.
 	 */
-#ifdef CONFIG_ARCH_ROCKCHIP
-	int (*set_release_callback)(void (*release_callback)(void *data),
-				    void *data);
-	void *(*get_release_callback_data)(void *callback);
-	/* after final dma_buf_put() */
-#endif
+
 	/**
 	 * @release:
 	 *
@@ -191,33 +209,6 @@
 	 * needs to be restarted.
 	 */
 	int (*begin_cpu_access)(struct dma_buf *, enum dma_data_direction);
-
-	/**
-	 * @begin_cpu_access_umapped:
-	 *
-	 * This is called as a result of the DMA_BUF_IOCTL_SYNC IOCTL being
-	 * called with the DMA_BUF_SYNC_START and DMA_BUF_SYNC_USER_MAPPED flags
-	 * set. It allows the exporter to ensure that the mmap(ed) portions of
-	 * the buffer are available for cpu access - the exporter might need to
-	 * allocate or swap-in and pin the backing storage.
-	 * The exporter also needs to ensure that cpu access is
-	 * coherent for the access direction. The direction can be used by the
-	 * exporter to optimize the cache flushing, i.e. access with a different
-	 * direction (read instead of write) might return stale or even bogus
-	 * data (e.g. when the exporter needs to copy the data to temporary
-	 * storage).
-	 *
-	 * This callback is optional.
-	 *
-	 * Returns:
-	 *
-	 * 0 on success or a negative error code on failure. This can for
-	 * example fail when the backing storage can't be allocated. Can also
-	 * return -ERESTARTSYS or -EINTR when the call has been interrupted and
-	 * needs to be restarted.
-	 */
-	int (*begin_cpu_access_umapped)(struct dma_buf *dmabuf,
-					enum dma_data_direction);
 
 	/**
 	 * @begin_cpu_access_partial:
@@ -274,28 +265,6 @@
 	int (*end_cpu_access)(struct dma_buf *, enum dma_data_direction);
 
 	/**
-	 * @end_cpu_access_umapped:
-	 *
-	 * This is called as result a of the DMA_BUF_IOCTL_SYNC IOCTL being
-	 * called with the DMA_BUF_SYNC_END and DMA_BUF_SYNC_USER_MAPPED flags
-	 * set. The exporter can use to limit cache flushing to only those parts
-	 * of the buffer which are mmap(ed) and to unpin any resources pinned in
-	 * @begin_cpu_access_umapped.
-	 * The result of any dma_buf kmap calls after end_cpu_access_umapped is
-	 * undefined.
-	 *
-	 * This callback is optional.
-	 *
-	 * Returns:
-	 *
-	 * 0 on success or a negative error code on failure. Can return
-	 * -ERESTARTSYS or -EINTR when the call has been interrupted and needs
-	 * to be restarted.
-	 */
-	int (*end_cpu_access_umapped)(struct dma_buf *dmabuf,
-				      enum dma_data_direction);
-
-	/**
 	 * @end_cpu_access_partial:
 	 *
 	 * This is called from dma_buf_end_cpu_access_partial() when the
@@ -316,9 +285,6 @@
 	int (*end_cpu_access_partial)(struct dma_buf *dmabuf,
 				      enum dma_data_direction,
 				      unsigned int offset, unsigned int len);
-
-	void *(*map)(struct dma_buf *, unsigned long);
-	void (*unmap)(struct dma_buf *, unsigned long, void *);
 
 	/**
 	 * @mmap:
@@ -388,8 +354,12 @@
 	 * will be populated with the buffer's flags.
 	 */
 	int (*get_flags)(struct dma_buf *dmabuf, unsigned long *flags);
+
+	ANDROID_KABI_RESERVE(1);
+	ANDROID_KABI_RESERVE(2);
 };
 
+#ifdef CONFIG_DMABUF_CACHE
 /**
  * dma_buf_destructor - dma-buf destructor function
  * @dmabuf:	[in]	pointer to dma-buf
@@ -401,21 +371,23 @@
  * won't be called.
  */
 typedef int (*dma_buf_destructor)(struct dma_buf *dmabuf, void *dtor_data);
+#endif
 
 /**
  * struct dma_buf - shared buffer object
  * @size: size of the buffer
  * @file: file pointer used for sharing buffers across, and for refcounting.
- * @attachments: list of dma_buf_attachment that denotes all devices attached.
+ * @attachments: list of dma_buf_attachment that denotes all devices attached,
+ *               protected by dma_resv lock.
  * @ops: dma_buf_ops associated with this buffer object.
  * @lock: used internally to serialize list manipulation, attach/detach and
- *        vmap/unmap, and accesses to name
+ *        vmap/unmap
  * @vmapping_counter: used internally to refcnt the vmaps
  * @vmap_ptr: the current vmap ptr if vmapping_counter > 0
  * @exp_name: name of the exporter; useful for debugging.
- * @name: userspace-provided name; useful for accounting and debugging.
- * @name_lock: lock to protect name.
- * @ktime: time (in jiffies) at which the buffer was born
+ * @name: userspace-provided name; useful for accounting and debugging,
+ *        protected by @resv.
+ * @name_lock: spinlock to protect name access
  * @owner: pointer to exporter module; used for refcounting when exporter is a
  *         kernel module.
  * @list_node: node for dma_buf accounting and debugging.
@@ -424,6 +396,7 @@
  * @poll: for userspace poll support
  * @cb_excl: for userspace poll support
  * @cb_shared: for userspace poll support
+ * @sysfs_entry: for exposing information about this buffer in sysfs.
  *
  * This represents a shared buffer, created by calling dma_buf_export(). The
  * userspace representation is a normal file descriptor, which can be created by
@@ -438,10 +411,6 @@
 	size_t size;
 	struct file *file;
 	struct list_head attachments;
-#ifdef CONFIG_ARCH_ROCKCHIP
-	struct list_head release_callbacks;
-	struct mutex release_lock;
-#endif
 	const struct dma_buf_ops *ops;
 	struct mutex lock;
 	unsigned vmapping_counter;
@@ -449,13 +418,10 @@
 	const char *exp_name;
 	const char *name;
 	spinlock_t name_lock;
-#if defined(CONFIG_DEBUG_FS)
-	ktime_t ktime;
-#endif
 	struct module *owner;
 	struct list_head list_node;
 	void *priv;
-	struct reservation_object *resv;
+	struct dma_resv *resv;
 
 	/* poll support */
 	wait_queue_head_t poll;
@@ -466,17 +432,70 @@
 
 		__poll_t active;
 	} cb_excl, cb_shared;
+#ifdef CONFIG_DMABUF_SYSFS_STATS
+	/* for sysfs stats */
+	struct dma_buf_sysfs_entry {
+		struct kobject kobj;
+		struct dma_buf *dmabuf;
+	} *sysfs_entry;
+#endif
+#ifdef CONFIG_DMABUF_CACHE
 	dma_buf_destructor dtor;
 	void *dtor_data;
-	atomic_t dent_count;
+	struct mutex cache_lock;
+#endif
+
+	ANDROID_KABI_RESERVE(1);
+	ANDROID_KABI_RESERVE(2);
+};
+
+/**
+ * struct dma_buf_attach_ops - importer operations for an attachment
+ *
+ * Attachment operations implemented by the importer.
+ */
+struct dma_buf_attach_ops {
+	/**
+	 * @allow_peer2peer:
+	 *
+	 * If this is set to true the importer must be able to handle peer
+	 * resources without struct pages.
+	 */
+	bool allow_peer2peer;
+
+	/**
+	 * @move_notify: [optional] notification that the DMA-buf is moving
+	 *
+	 * If this callback is provided the framework can avoid pinning the
+	 * backing store while mappings exists.
+	 *
+	 * This callback is called with the lock of the reservation object
+	 * associated with the dma_buf held and the mapping function must be
+	 * called with this lock held as well. This makes sure that no mapping
+	 * is created concurrently with an ongoing move operation.
+	 *
+	 * Mappings stay valid and are not directly affected by this callback.
+	 * But the DMA-buf can now be in a different physical location, so all
+	 * mappings should be destroyed and re-created as soon as possible.
+	 *
+	 * New mappings can be created after this callback returns, and will
+	 * point to the new location of the DMA-buf.
+	 */
+	void (*move_notify)(struct dma_buf_attachment *attach);
 };
 
 /**
  * struct dma_buf_attachment - holds device-buffer attachment data
  * @dmabuf: buffer for this attachment.
  * @dev: device attached to the buffer.
- * @node: list of dma_buf_attachment.
+ * @node: list of dma_buf_attachment, protected by dma_resv lock of the dmabuf.
+ * @sgt: cached mapping.
+ * @dir: direction of cached mapping.
+ * @peer2peer: true if the importer can handle peer resources without pages.
  * @priv: exporter specific attachment data.
+ * @importer_ops: importer operations for this attachment, if provided
+ * dma_buf_map/unmap_attachment() must be called with the dma_resv lock held.
+ * @importer_priv: importer specific attachment data.
  * @dma_map_attrs: DMA attributes to be used when the exporter maps the buffer
  * through dma_buf_map_attachment.
  *
@@ -493,8 +512,16 @@
 	struct dma_buf *dmabuf;
 	struct device *dev;
 	struct list_head node;
+	struct sg_table *sgt;
+	enum dma_data_direction dir;
+	bool peer2peer;
+	const struct dma_buf_attach_ops *importer_ops;
+	void *importer_priv;
 	void *priv;
 	unsigned long dma_map_attrs;
+
+	ANDROID_KABI_RESERVE(1);
+	ANDROID_KABI_RESERVE(2);
 };
 
 /**
@@ -516,8 +543,11 @@
 	const struct dma_buf_ops *ops;
 	size_t size;
 	int flags;
-	struct reservation_object *resv;
+	struct dma_resv *resv;
 	void *priv;
+
+	ANDROID_KABI_RESERVE(1);
+	ANDROID_KABI_RESERVE(2);
 };
 
 /**
@@ -545,18 +575,46 @@
 	get_file(dmabuf->file);
 }
 
-#ifdef CONFIG_ARCH_ROCKCHIP
-int dma_buf_set_release_callback(struct dma_buf *dmabuf,
-				 void (*callback)(void *), void *data);
+/**
+ * dma_buf_is_dynamic - check if a DMA-buf uses dynamic mappings.
+ * @dmabuf: the DMA-buf to check
+ *
+ * Returns true if a DMA-buf exporter wants to be called with the dma_resv
+ * locked for the map/unmap callbacks, false if it doesn't wants to be called
+ * with the lock held.
+ */
+static inline bool dma_buf_is_dynamic(struct dma_buf *dmabuf)
+{
+	return !!dmabuf->ops->pin;
+}
 
-void *dma_buf_get_release_callback_data(struct dma_buf *dmabuf,
-					void (*callback)(void *));
-#endif
+/**
+ * dma_buf_attachment_is_dynamic - check if a DMA-buf attachment uses dynamic
+ * mappinsg
+ * @attach: the DMA-buf attachment to check
+ *
+ * Returns true if a DMA-buf importer wants to call the map/unmap functions with
+ * the dma_resv lock held.
+ */
+static inline bool
+dma_buf_attachment_is_dynamic(struct dma_buf_attachment *attach)
+{
+	return !!attach->importer_ops;
+}
 
+int get_each_dmabuf(int (*callback)(const struct dma_buf *dmabuf,
+		    void *private), void *private);
+int is_dma_buf_file(struct file *file);
 struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
-							struct device *dev);
+					  struct device *dev);
+struct dma_buf_attachment *
+dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
+		       const struct dma_buf_attach_ops *importer_ops,
+		       void *importer_priv);
 void dma_buf_detach(struct dma_buf *dmabuf,
-				struct dma_buf_attachment *dmabuf_attach);
+		    struct dma_buf_attachment *attach);
+int dma_buf_pin(struct dma_buf_attachment *attach);
+void dma_buf_unpin(struct dma_buf_attachment *attach);
 
 struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info);
 
@@ -568,6 +626,7 @@
 					enum dma_data_direction);
 void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,
 				enum dma_data_direction);
+void dma_buf_move_notify(struct dma_buf *dma_buf);
 int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
 			     enum dma_data_direction dir);
 int dma_buf_begin_cpu_access_partial(struct dma_buf *dma_buf,
@@ -578,16 +637,16 @@
 int dma_buf_end_cpu_access_partial(struct dma_buf *dma_buf,
 				     enum dma_data_direction dir,
 				     unsigned int offset, unsigned int len);
-void *dma_buf_kmap(struct dma_buf *, unsigned long);
-void dma_buf_kunmap(struct dma_buf *, unsigned long, void *);
 
 int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *,
 		 unsigned long);
 void *dma_buf_vmap(struct dma_buf *);
 void dma_buf_vunmap(struct dma_buf *, void *vaddr);
+long dma_buf_set_name(struct dma_buf *dmabuf, const char *name);
 int dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags);
 int dma_buf_get_uuid(struct dma_buf *dmabuf, uuid_t *uuid);
 
+#ifdef CONFIG_DMABUF_CACHE
 /**
  * dma_buf_set_destructor - set the dma-buf's destructor
  * @dmabuf:		[in]	pointer to dma-buf
@@ -601,5 +660,16 @@
 	dmabuf->dtor = dtor;
 	dmabuf->dtor_data = dtor_data;
 }
+#endif
+
+#if IS_ENABLED(CONFIG_RK_DMABUF_DEBUG)
+void dma_buf_reset_peak_size(void);
+size_t dma_buf_get_peak_size(void);
+size_t dma_buf_get_total_size(void);
+#else
+static inline void dma_buf_reset_peak_size(void) {}
+static inline size_t dma_buf_get_peak_size(void) { return 0; }
+static inline size_t dma_buf_get_total_size(void) { return 0; }
+#endif
 
 #endif /* __DMA_BUF_H__ */

--
Gitblit v1.6.2