فهرست منبع

mm-drivers: hw_fence: add timestamp to the queue

Add qtimer timestamps to queue payloads.
This timestamp is to be updated by the client
that adds the entry to the queue.

Change-Id: I69dd4420ec18b7470f99d5cfe46129c10b3f3391
Signed-off-by: Ingrid Gallardo <[email protected]>
Ingrid Gallardo 3 سال پیش
والد
کامیت
c344a18254
3فایلهای تغییر یافته به همراه89 افزوده شده و 1 حذف شده
  1. 2 1
      hw_fence/include/hw_fence_drv_priv.h
  2. 86 0
      hw_fence/src/hw_fence_drv_debug.c
  3. 1 0
      hw_fence/src/hw_fence_drv_priv.c

+ 2 - 1
hw_fence/include/hw_fence_drv_priv.h

@@ -326,6 +326,7 @@ struct hw_fence_driver_data {
  * @error: error code for this fence, fence controller receives this
  *		  error from the signaling client through the tx queue and
  *		  propagates the error to the waiting client through rx queue
+ * @timestamp: qtime when the payload is written into the queue
  */
 struct msm_hw_fence_queue_payload {
 	u64 ctxt_id;
@@ -333,7 +334,7 @@ struct msm_hw_fence_queue_payload {
 	u64 hash;
 	u64 flags;
 	u32 error;
-	u32 unused; /* align to 64-bit */
+	u32 timestamp;
 };
 
 /**

+ 86 - 0
hw_fence/src/hw_fence_drv_debug.c

@@ -536,6 +536,85 @@ static int dump_full_table(struct hw_fence_driver_data *drv_data, char *buf, u32
 	return len;
 }
 
+/**
+ * hw_fence_dbg_dump_queues_wr() - debugfs wr to dump the hw-fences queues.
+ * @file: file handler.
+ * @user_buf: user buffer content for debugfs.
+ * @count: size of the user buffer.
+ * @ppos: position offset of the user buffer.
+ *
+ * This debugfs dumps the hw-fence queues. Takes as input the desired client to dump.
+ * Dumps to debug msgs the contents of the TX and RX queues for that client, if they exist.
+ */
+static ssize_t hw_fence_dbg_dump_queues_wr(struct file *file, const char __user *user_buf,
+	size_t count, loff_t *ppos)
+{
+	struct hw_fence_driver_data *drv_data;
+	struct msm_hw_fence_queue *rx_queue;
+	struct msm_hw_fence_queue *tx_queue;
+	u64 hash, ctx_id, seqno, timestamp, flags;
+	u32 *read_ptr, error;
+	int client_id, i;
+	struct msm_hw_fence_queue_payload *read_ptr_payload;
+
+	if (!file || !file->private_data) {
+		HWFNC_ERR("unexpected data %d\n", file);
+		return -EINVAL;
+	}
+	drv_data = file->private_data;
+
+	client_id = _get_debugfs_input_client(file, user_buf, count, ppos, &drv_data);
+	if (client_id < 0)
+		return -EINVAL;
+
+	if (!drv_data->clients[client_id] ||
+		IS_ERR_OR_NULL(&drv_data->clients[client_id]->queues[HW_FENCE_RX_QUEUE - 1]) ||
+		IS_ERR_OR_NULL(&drv_data->clients[client_id]->queues[HW_FENCE_TX_QUEUE - 1])) {
+		HWFNC_ERR("client %d not initialized\n", client_id);
+		return -EINVAL;
+	}
+
+	HWFNC_DBG_L("Queues for client %d\n", client_id);
+
+	rx_queue = &drv_data->clients[client_id]->queues[HW_FENCE_RX_QUEUE - 1];
+	tx_queue = &drv_data->clients[client_id]->queues[HW_FENCE_TX_QUEUE - 1];
+
+	HWFNC_DBG_L("-------RX QUEUE------\n");
+	for (i = 0; i < drv_data->hw_fence_queue_entries; i++) {
+		read_ptr = ((u32 *)rx_queue->va_queue +
+			(i * (sizeof(struct msm_hw_fence_queue_payload) / sizeof(u32))));
+		read_ptr_payload = (struct msm_hw_fence_queue_payload *)read_ptr;
+
+		ctx_id = readq_relaxed(&read_ptr_payload->ctxt_id);
+		seqno = readq_relaxed(&read_ptr_payload->seqno);
+		hash = readq_relaxed(&read_ptr_payload->hash);
+		flags = readq_relaxed(&read_ptr_payload->flags);
+		error = readl_relaxed(&read_ptr_payload->error);
+		timestamp = readl_relaxed(&read_ptr_payload->timestamp);
+
+		HWFNC_DBG_L("rx[%d]: hash:%d ctx:%llu seqno:%llu f:%llu err:%u time:%u\n",
+			i, hash, ctx_id, seqno, flags, error, timestamp);
+	}
+
+	HWFNC_DBG_L("-------TX QUEUE------\n");
+	for (i = 0; i < drv_data->hw_fence_queue_entries; i++) {
+		read_ptr = ((u32 *)tx_queue->va_queue +
+			(i * (sizeof(struct msm_hw_fence_queue_payload) / sizeof(u32))));
+		read_ptr_payload = (struct msm_hw_fence_queue_payload *)read_ptr;
+
+		ctx_id = readq_relaxed(&read_ptr_payload->ctxt_id);
+		seqno = readq_relaxed(&read_ptr_payload->seqno);
+		hash = readq_relaxed(&read_ptr_payload->hash);
+		flags = readq_relaxed(&read_ptr_payload->flags);
+		error = readl_relaxed(&read_ptr_payload->error);
+		timestamp = readl_relaxed(&read_ptr_payload->timestamp);
+		HWFNC_DBG_L("tx[%d]: hash:%d ctx:%llu seqno:%llu f:%llu err:%u time:%u\n",
+			i, hash, ctx_id, seqno, flags, error, timestamp);
+	}
+
+	return count;
+}
+
 /**
  * hw_fence_dbg_dump_table_rd() - debugfs read to dump the hw-fences table.
  * @file: file handler.
@@ -862,6 +941,11 @@ static const struct file_operations hw_fence_dump_table_fops = {
 	.read = hw_fence_dbg_dump_table_rd,
 };
 
+static const struct file_operations hw_fence_dump_queues_fops = {
+	.open = simple_open,
+	.write = hw_fence_dbg_dump_queues_wr,
+};
+
 static const struct file_operations hw_fence_create_join_fence_fops = {
 	.open = simple_open,
 	.write = hw_fence_dbg_create_join_fence,
@@ -908,6 +992,8 @@ int hw_fence_debug_debugfs_register(struct hw_fence_driver_data *drv_data)
 	debugfs_create_u32("hw_fence_debug_level", 0600, debugfs_root, &msm_hw_fence_debug_level);
 	debugfs_create_file("hw_fence_dump_table", 0600, debugfs_root, drv_data,
 		&hw_fence_dump_table_fops);
+	debugfs_create_file("hw_fence_dump_queues", 0600, debugfs_root, drv_data,
+		&hw_fence_dump_queues_fops);
 	debugfs_create_file("hw_sync", 0600, debugfs_root, NULL, &hw_sync_debugfs_fops);
 
 	return 0;

+ 1 - 0
hw_fence/src/hw_fence_drv_priv.c

@@ -324,6 +324,7 @@ int hw_fence_update_queue(struct hw_fence_driver_data *drv_data,
 	writeq_relaxed(hash, &write_ptr_payload->hash);
 	writeq_relaxed(flags, &write_ptr_payload->flags);
 	writel_relaxed(error, &write_ptr_payload->error);
+	writel_relaxed(hw_fence_get_qtime(drv_data), &write_ptr_payload->timestamp);
 
 	/* update memory for the message */
 	wmb();