summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurora zuma automerger <aurora-zuma-automerger@google.com>2023-02-13 12:41:16 +0000
committerCopybara-Service <copybara-worker@google.com>2023-02-13 06:02:55 -0800
commitdb1cd6d6c90112002c196977d50d0e7393272101 (patch)
treee773a062d097c54cb50f9c2696e77dbbae8c61f2
parent557924e23d1d1bb4a5e0242f2af42f3083c6a00c (diff)
downloadzuma-db1cd6d6c90112002c196977d50d0e7393272101.tar.gz
gxp: [Copybara Auto Merge] Merge branch 'zuma' into 'android14-gs-pixel-5.15'
gxp: bump to version 1.9 Bug: 245751727 Bug: 268449263 gxp: unittest: add a unittest for gxp_mapping_iova_log Bug: 245751727 (repeat) gxp: Add a module flag to enable IOVA-space logging Bug: 245751727 (repeat) gxp: check wakelock cnt before handling MCU fw crash Bug: 267714120 GitOrigin-RevId: 29fa86963245e80c3f646b8c62fd00561278f928 Change-Id: I2a3269423436749b214637ecc1d9e641347d7b44
-rw-r--r--gxp-common-platform.c11
-rw-r--r--gxp-dmabuf.c1
-rw-r--r--gxp-mapping.c35
-rw-r--r--gxp-mapping.h22
-rw-r--r--gxp-mcu-firmware.c12
-rw-r--r--gxp.h2
6 files changed, 82 insertions, 1 deletions
diff --git a/gxp-common-platform.c b/gxp-common-platform.c
index 66be9c0..68accfa 100644
--- a/gxp-common-platform.c
+++ b/gxp-common-platform.c
@@ -258,6 +258,9 @@ static int gxp_map_buffer(struct gxp_client *client,
goto error_remove;
}
+ gxp_mapping_iova_log(client, map,
+ GXP_IOVA_LOG_MAP | GXP_IOVA_LOG_BUFFER);
+
/*
* The virtual device acquired its own reference to the mapping when
* it was stored in the VD's records. Release the reference from
@@ -315,6 +318,8 @@ static int gxp_unmap_buffer(struct gxp_client *client,
WARN_ON(map->host_address != ibuf.host_address);
gxp_vd_mapping_remove(client->vd, map);
+ gxp_mapping_iova_log(client, map,
+ GXP_IOVA_LOG_UNMAP | GXP_IOVA_LOG_BUFFER);
/* Release the reference from gxp_vd_mapping_search() */
gxp_mapping_put(map);
@@ -1316,6 +1321,9 @@ static int gxp_map_dmabuf(struct gxp_client *client,
ret = -EFAULT;
}
+ gxp_mapping_iova_log(client, mapping,
+ GXP_IOVA_LOG_MAP | GXP_IOVA_LOG_DMABUF);
+
out_put:
/*
* Release the reference from creating the dmabuf mapping
@@ -1371,6 +1379,9 @@ static int gxp_unmap_dmabuf(struct gxp_client *client,
/* Remove the mapping from its VD, releasing the VD's reference */
gxp_vd_mapping_remove(client->vd, mapping);
+ gxp_mapping_iova_log(client, mapping,
+ GXP_IOVA_LOG_UNMAP | GXP_IOVA_LOG_DMABUF);
+
/* Release the reference from gxp_vd_mapping_search() */
gxp_mapping_put(mapping);
diff --git a/gxp-dmabuf.c b/gxp-dmabuf.c
index 85fd832..92c419d 100644
--- a/gxp-dmabuf.c
+++ b/gxp-dmabuf.c
@@ -101,6 +101,7 @@ struct gxp_mapping *gxp_dmabuf_map(struct gxp_dev *gxp,
dmabuf_mapping->mapping.domain = domain;
dmabuf_mapping->mapping.device_address = sg_dma_address(sgt->sgl);
dmabuf_mapping->mapping.dir = dir;
+ dmabuf_mapping->mapping.size = dmabuf->size;
dmabuf_mapping->dmabuf = dmabuf;
dmabuf_mapping->attachment = attachment;
dmabuf_mapping->sgt = sgt;
diff --git a/gxp-mapping.c b/gxp-mapping.c
index 0188fad..398ff05 100644
--- a/gxp-mapping.c
+++ b/gxp-mapping.c
@@ -6,16 +6,51 @@
*/
#include <linux/dma-mapping.h>
+#include <linux/ktime.h>
#include <linux/mm.h>
#include <linux/mmap_lock.h>
+#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include "gxp-client.h"
#include "gxp-debug-dump.h"
#include "gxp-dma.h"
#include "gxp-internal.h"
#include "gxp-mapping.h"
+#if IS_ENABLED(CONFIG_GXP_TEST)
+/* expose this variable to have unit tests set it dynamically */
+bool gxp_log_iova;
+#else
+static bool gxp_log_iova;
+#endif
+
+module_param_named(log_iova, gxp_log_iova, bool, 0660);
+
+void gxp_mapping_iova_log(struct gxp_client *client, struct gxp_mapping *map,
+ u8 mask)
+{
+ static bool is_first_log = true;
+ struct device *dev = client->gxp->dev;
+ const char *op = mask & GXP_IOVA_LOG_MAP ? "MAP" : "UNMAP";
+ const char *buf_type = mask & GXP_IOVA_LOG_DMABUF ? "DMABUF" : "BUFFER";
+
+ if (likely(!gxp_log_iova))
+ return;
+
+ if (is_first_log) {
+ dev_info(
+ dev,
+ "iova_log_start: operation, buf_type, tgid, pid, host_address, device_address, size");
+ is_first_log = false;
+ }
+
+ dev_info(dev, "iova_log: %s, %s, %d, %d, %#llx, %#llx, %zu", op,
+ buf_type, client->pid, client->tgid, map->host_address,
+ map->device_address, map->size);
+}
+
/* Destructor for a mapping created with `gxp_mapping_create()` */
static void destroy_mapping(struct gxp_mapping *mapping)
{
diff --git a/gxp-mapping.h b/gxp-mapping.h
index 18454e6..8d970ef 100644
--- a/gxp-mapping.h
+++ b/gxp-mapping.h
@@ -16,6 +16,16 @@
#include "gxp-internal.h"
+#if IS_ENABLED(CONFIG_GXP_TEST)
+/* expose this variable to have unit tests set it dynamically */
+extern bool gxp_log_iova;
+#endif
+
+#define GXP_IOVA_LOG_UNMAP (0u << 0)
+#define GXP_IOVA_LOG_MAP (1u << 0)
+#define GXP_IOVA_LOG_BUFFER (0u << 1)
+#define GXP_IOVA_LOG_DMABUF (1u << 1)
+
struct gxp_mapping {
struct rb_node node;
refcount_t refcount;
@@ -55,6 +65,18 @@ struct gxp_mapping {
};
/**
+ * gxp_mapping_iova_log() - Log IOVA mapping details
+ * @client: The client to create/destroy the mapping for
+ * @map: The mapping being handled
+ * @mask: The mask combination of GXP_IOVA_LOG_*
+ *
+ * Log IOVA mapping details for each map/unmap operation.
+ * Log the field names of the data before first mapping is logged.
+ */
+void gxp_mapping_iova_log(struct gxp_client *client, struct gxp_mapping *map,
+ u8 mask);
+
+/**
* gxp_mapping_create() - Create a mapping for a user buffer
* @gxp: The GXP device to create the mapping for
* @domain: The iommu domain the mapping for
diff --git a/gxp-mcu-firmware.c b/gxp-mcu-firmware.c
index 956ccce..be0fbad 100644
--- a/gxp-mcu-firmware.c
+++ b/gxp-mcu-firmware.c
@@ -575,6 +575,17 @@ void gxp_mcu_firmware_crash_handler(struct gxp_dev *gxp,
mutex_lock(&gxp->wakelock_mgr->lock);
/*
+ * By the race, if all clients left earlier than this handler, all block wakleock should be
+ * already released and the BLK is turned off. We don't have to rescue the MCU firmware.
+ */
+ if (!gxp->wakelock_mgr->count) {
+ dev_info(
+ gxp->dev,
+ "The block wakelock is already released, skip restarting MCU firmware");
+ goto unlock_wakelock_mgr;
+ }
+
+ /*
* Discard all pending/unconsumed UCI responses and change the state of all virtual devices
* to GXP_VD_UNAVAILABLE. From now on, all clients cannot request new UCI commands.
*/
@@ -618,6 +629,7 @@ void gxp_mcu_firmware_crash_handler(struct gxp_dev *gxp,
out:
mutex_unlock(&mcu_fw->lock);
+unlock_wakelock_mgr:
mutex_unlock(&gxp->wakelock_mgr->lock);
up_write(&gxp->vd_semaphore);
list_for_each_entry (client, &gxp->client_list, list_entry) {
diff --git a/gxp.h b/gxp.h
index afc9f87..5bb868a 100644
--- a/gxp.h
+++ b/gxp.h
@@ -13,7 +13,7 @@
/* Interface Version */
#define GXP_INTERFACE_VERSION_MAJOR 1
-#define GXP_INTERFACE_VERSION_MINOR 8
+#define GXP_INTERFACE_VERSION_MINOR 9
#define GXP_INTERFACE_VERSION_BUILD 0
/*