All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Refactor and clean up codes of mst
@ 2023-08-04  6:20 ` Wayne Lin
  0 siblings, 0 replies; 38+ messages in thread
From: Wayne Lin @ 2023-08-04  6:20 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: jani.nikula, jerry.zuo, Wayne Lin

This patch set is mainly trying to organize the mst code today a bit.
Like to clarify and organize the sequence of mst payload allocation and
removement.And also clean up some redundant codes today.

The main refactor one is the patch
"drm/mst: Refactor the flow for payload allocation/removement"
which is adding a new enum variable in stuct drm_dp_mst_atomic_payload
to represent the status of paylad alloction, and then handle the payload
accordingly. Besides, rename some drm mst fnctions to better express the
behind idea.

The other two patches are mainly to clean up unnecessary codes.

Wayne Lin (3):
  drm/mst: delete unnecessary case in drm_dp_add_payload_part2()
  drm/mst: Refactor the flow for payload allocation/removement
  drm/mst: adjust the function drm_dp_remove_payload_part2()

 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  60 +-----
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 189 +++++++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  13 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  11 +-
 include/drm/display/drm_dp_mst_helper.h       |  22 +-
 5 files changed, 158 insertions(+), 137 deletions(-)

-- 
2.37.3


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 0/3] Refactor and clean up codes of mst
@ 2023-08-04  6:20 ` Wayne Lin
  0 siblings, 0 replies; 38+ messages in thread
From: Wayne Lin @ 2023-08-04  6:20 UTC (permalink / raw)
  To: dri-devel, amd-gfx
  Cc: jani.nikula, imre.deak, jerry.zuo, Wayne Lin, harry.wentland,
	ville.syrjala

This patch set is mainly trying to organize the mst code today a bit.
Like to clarify and organize the sequence of mst payload allocation and
removement.And also clean up some redundant codes today.

The main refactor one is the patch
"drm/mst: Refactor the flow for payload allocation/removement"
which is adding a new enum variable in stuct drm_dp_mst_atomic_payload
to represent the status of paylad alloction, and then handle the payload
accordingly. Besides, rename some drm mst fnctions to better express the
behind idea.

The other two patches are mainly to clean up unnecessary codes.

Wayne Lin (3):
  drm/mst: delete unnecessary case in drm_dp_add_payload_part2()
  drm/mst: Refactor the flow for payload allocation/removement
  drm/mst: adjust the function drm_dp_remove_payload_part2()

 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  60 +-----
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 189 +++++++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  13 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  11 +-
 include/drm/display/drm_dp_mst_helper.h       |  22 +-
 5 files changed, 158 insertions(+), 137 deletions(-)

-- 
2.37.3


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 1/3] drm/mst: delete unnecessary case in drm_dp_add_payload_part2()
  2023-08-04  6:20 ` Wayne Lin
@ 2023-08-04  6:20   ` Wayne Lin
  -1 siblings, 0 replies; 38+ messages in thread
From: Wayne Lin @ 2023-08-04  6:20 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: jani.nikula, jerry.zuo, Wayne Lin

[Why]
There is no need to consider payload->delete case since we won't call
drm_dp_add_payload_part2() to create a payload when we're about to
remove it.

[How]
Delete unnecessary case to simplify the code.

Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index ed96cfcfa304..4d80426757ab 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3411,12 +3411,8 @@ int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
 
 	ret = drm_dp_create_payload_step2(mgr, payload);
 	if (ret < 0) {
-		if (!payload->delete)
-			drm_err(mgr->dev, "Step 2 of creating MST payload for %p failed: %d\n",
-				payload->port, ret);
-		else
-			drm_dbg_kms(mgr->dev, "Step 2 of removing MST payload for %p failed: %d\n",
-				    payload->port, ret);
+		drm_err(mgr->dev, "Step 2 of creating MST payload for %p failed: %d\n",
+			payload->port, ret);
 	}
 
 	return ret;
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 1/3] drm/mst: delete unnecessary case in drm_dp_add_payload_part2()
@ 2023-08-04  6:20   ` Wayne Lin
  0 siblings, 0 replies; 38+ messages in thread
From: Wayne Lin @ 2023-08-04  6:20 UTC (permalink / raw)
  To: dri-devel, amd-gfx
  Cc: jani.nikula, imre.deak, jerry.zuo, Wayne Lin, harry.wentland,
	ville.syrjala

[Why]
There is no need to consider payload->delete case since we won't call
drm_dp_add_payload_part2() to create a payload when we're about to
remove it.

[How]
Delete unnecessary case to simplify the code.

Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index ed96cfcfa304..4d80426757ab 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3411,12 +3411,8 @@ int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
 
 	ret = drm_dp_create_payload_step2(mgr, payload);
 	if (ret < 0) {
-		if (!payload->delete)
-			drm_err(mgr->dev, "Step 2 of creating MST payload for %p failed: %d\n",
-				payload->port, ret);
-		else
-			drm_dbg_kms(mgr->dev, "Step 2 of removing MST payload for %p failed: %d\n",
-				    payload->port, ret);
+		drm_err(mgr->dev, "Step 2 of creating MST payload for %p failed: %d\n",
+			payload->port, ret);
 	}
 
 	return ret;
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement
  2023-08-04  6:20 ` Wayne Lin
@ 2023-08-04  6:20   ` Wayne Lin
  -1 siblings, 0 replies; 38+ messages in thread
From: Wayne Lin @ 2023-08-04  6:20 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: jani.nikula, jerry.zuo, Wayne Lin

[Why]
Today, the allocation/deallocation steps and status is a bit unclear.

For instance, payload->vc_start_slot = -1 stands for "the failure of
updating DPCD payload ID table" and can also represent as "payload is not
allocated yet". These two cases should be handled differently and hence
better to distinguish them for better understanding.

[How]
Define enumeration - ALLOCATION_LOCAL, ALLOCATION_DFP and ALLOCATION_REMOTE
to distinguish different allocation status. Adjust the code to handle
different status accordingly for better understanding the sequence of
payload allocation and payload removement.

For payload creation, the procedure should look like this:
DRM part 1:
* step 1 - update sw mst mgr variables to add a new payload
* step 2 - add payload at immediate DFP DPCD payload table

Driver:
* Add new payload in HW and sync up with DFP by sending ACT

DRM Part 2:
* Send ALLOCATE_PAYLOAD sideband message to allocate bandwidth along the
  virtual channel.

And as for payload removement, the procedure should look like this:
DRM part 1:
* step 1 - Send ALLOCATE_PAYLOAD sideband message to release bandwidth
           along the virtual channel
* step 2 - Clear payload allocation at immediate DFP DPCD payload table

Driver:
* Remove the payload in HW and sync up with DFP by sending ACT

DRM part 2:
* update sw mst mgr variables to remove the payload

Note that it's fine to fail when communicate with the branch device
connected at immediate downstrean-facing port, but updating variables of
SW mst mgr and HW configuration should be conducted anyway. That's because
it's under commit_tail and we need to complete the HW programming.

Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  20 ++-
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 159 +++++++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  18 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  15 +-
 include/drm/display/drm_dp_mst_helper.h       |  23 ++-
 5 files changed, 152 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index d9a482908380..9ad509279b0a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -219,7 +219,7 @@ static void dm_helpers_construct_old_payload(
 	/* Set correct time_slots/PBN of old payload.
 	 * other fields (delete & dsc_enabled) in
 	 * struct drm_dp_mst_atomic_payload are don't care fields
-	 * while calling drm_dp_remove_payload()
+	 * while calling drm_dp_remove_payload_part2()
 	 */
 	for (i = 0; i < current_link_table.stream_count; i++) {
 		dc_alloc =
@@ -262,13 +262,12 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 
 	mst_mgr = &aconnector->mst_root->mst_mgr;
 	mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
-
-	/* It's OK for this to fail */
 	new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
 
 	if (enable) {
 		target_payload = new_payload;
 
+		/* It's OK for this to fail */
 		drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload);
 	} else {
 		/* construct old payload by VCPI*/
@@ -276,7 +275,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 						new_payload, &old_payload);
 		target_payload = &old_payload;
 
-		drm_dp_remove_payload(mst_mgr, mst_state, &old_payload, new_payload);
+		drm_dp_remove_payload_part1(mst_mgr, mst_state, new_payload);
 	}
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
@@ -342,7 +341,7 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_dp_mst_topology_state *mst_state;
 	struct drm_dp_mst_topology_mgr *mst_mgr;
-	struct drm_dp_mst_atomic_payload *payload;
+	struct drm_dp_mst_atomic_payload *new_payload, *old_payload;
 	enum mst_progress_status set_flag = MST_ALLOCATE_NEW_PAYLOAD;
 	enum mst_progress_status clr_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 	int ret = 0;
@@ -355,15 +354,20 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	mst_mgr = &aconnector->mst_root->mst_mgr;
 	mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
 
-	payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
+	new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
 
 	if (!enable) {
 		set_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 		clr_flag = MST_ALLOCATE_NEW_PAYLOAD;
 	}
 
-	if (enable)
-		ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, payload);
+	if (enable) {
+		ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload);
+	} else {
+		dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
+						 new_payload, old_payload);
+		drm_dp_remove_payload_part2(mst_mgr, mst_state, old_payload, new_payload);
+	}
 
 	if (ret) {
 		amdgpu_dm_set_mst_status(&aconnector->mst_status,
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 4d80426757ab..e04f87ff755a 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3255,15 +3255,15 @@ int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
 }
 EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
 
-static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
-				       struct drm_dp_mst_atomic_payload *payload)
+static int drm_dp_create_payload_at_dfp(struct drm_dp_mst_topology_mgr *mgr,
+					struct drm_dp_mst_atomic_payload *payload)
 {
 	return drm_dp_dpcd_write_payload(mgr, payload->vcpi, payload->vc_start_slot,
 					 payload->time_slots);
 }
 
-static int drm_dp_create_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
-				       struct drm_dp_mst_atomic_payload *payload)
+static int drm_dp_create_payload_to_remote(struct drm_dp_mst_topology_mgr *mgr,
+					   struct drm_dp_mst_atomic_payload *payload)
 {
 	int ret;
 	struct drm_dp_mst_port *port = drm_dp_mst_topology_get_port_validated(mgr, payload->port);
@@ -3276,17 +3276,20 @@ static int drm_dp_create_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
 	return ret;
 }
 
-static int drm_dp_destroy_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
-					struct drm_dp_mst_topology_state *mst_state,
-					struct drm_dp_mst_atomic_payload *payload)
+static void drm_dp_destroy_payload_at_remote_and_dfp(struct drm_dp_mst_topology_mgr *mgr,
+						     struct drm_dp_mst_topology_state *mst_state,
+						     struct drm_dp_mst_atomic_payload *payload)
 {
 	drm_dbg_kms(mgr->dev, "\n");
 
 	/* it's okay for these to fail */
-	drm_dp_payload_send_msg(mgr, payload->port, payload->vcpi, 0);
-	drm_dp_dpcd_write_payload(mgr, payload->vcpi, payload->vc_start_slot, 0);
+	if (payload->payload_allocation_status == DRM_DP_MST_PAYLOAD_ALLOCATION_REMOTE) {
+		drm_dp_payload_send_msg(mgr, payload->port, payload->vcpi, 0);
+		payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_DFP;
+	}
 
-	return 0;
+	if (payload->payload_allocation_status == DRM_DP_MST_PAYLOAD_ALLOCATION_DFP)
+		drm_dp_dpcd_write_payload(mgr, payload->vcpi, payload->vc_start_slot, 0);
 }
 
 /**
@@ -3296,81 +3299,105 @@ static int drm_dp_destroy_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
  * @payload: The payload to write
  *
  * Determines the starting time slot for the given payload, and programs the VCPI for this payload
- * into hardware. After calling this, the driver should generate ACT and payload packets.
+ * into the DPCD of DPRX. After calling this, the driver should generate ACT and payload packets.
  *
- * Returns: 0 on success, error code on failure. In the event that this fails,
- * @payload.vc_start_slot will also be set to -1.
+ * Returns: 0 on success, error code on failure.
  */
 int drm_dp_add_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
 			     struct drm_dp_mst_topology_state *mst_state,
 			     struct drm_dp_mst_atomic_payload *payload)
 {
 	struct drm_dp_mst_port *port;
-	int ret;
+	int ret = 0;
+	bool allocate = true;
+
+	/* Update mst mgr info */
+	if (mgr->payload_count == 0)
+		mgr->next_start_slot = mst_state->start_slot;
+
+	payload->vc_start_slot = mgr->next_start_slot;
+
+	mgr->payload_count++;
+	mgr->next_start_slot += payload->time_slots;
 
+	/* Allocate payload to immediate downstream facing port */
 	port = drm_dp_mst_topology_get_port_validated(mgr, payload->port);
 	if (!port) {
 		drm_dbg_kms(mgr->dev,
-			    "VCPI %d for port %p not in topology, not creating a payload\n",
+			    "VCPI %d for port %p not in topology, not creating a payload to remote\n",
 			    payload->vcpi, payload->port);
-		payload->vc_start_slot = -1;
-		return 0;
+		allocate = false;
 	}
 
-	if (mgr->payload_count == 0)
-		mgr->next_start_slot = mst_state->start_slot;
-
-	payload->vc_start_slot = mgr->next_start_slot;
+	if (allocate) {
+		ret = drm_dp_create_payload_at_dfp(mgr, payload);
+		if (ret < 0)
+			drm_warn(mgr->dev, "Failed to create MST payload for port %p: %d\n",
+				 payload->port, ret);
 
-	ret = drm_dp_create_payload_step1(mgr, payload);
-	drm_dp_mst_topology_put_port(port);
-	if (ret < 0) {
-		drm_warn(mgr->dev, "Failed to create MST payload for port %p: %d\n",
-			 payload->port, ret);
-		payload->vc_start_slot = -1;
-		return ret;
 	}
 
-	mgr->payload_count++;
-	mgr->next_start_slot += payload->time_slots;
+	payload->payload_allocation_status =
+		(!allocate || ret < 0) ? DRM_DP_MST_PAYLOAD_ALLOCATION_LOCAL :
+								DRM_DP_MST_PAYLOAD_ALLOCATION_DFP;
 
-	return 0;
+	drm_dp_mst_topology_put_port(port);
+
+	return ret;
 }
 EXPORT_SYMBOL(drm_dp_add_payload_part1);
 
 /**
- * drm_dp_remove_payload() - Remove an MST payload
+ * drm_dp_remove_payload_part1() - Remove an MST payload along the virtual channel
  * @mgr: Manager to use.
  * @mst_state: The MST atomic state
- * @old_payload: The payload with its old state
- * @new_payload: The payload to write
+ * @payload: The payload to remove
  *
- * Removes a payload from an MST topology if it was successfully assigned a start slot. Also updates
- * the starting time slots of all other payloads which would have been shifted towards the start of
- * the VC table as a result. After calling this, the driver should generate ACT and payload packets.
+ * Removes a payload along the virtual channel if it was successfully allocated.
+ * After calling this, the driver should set HW to generate ACT and then switch to new
+ * payload allocation state.
  */
-void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr,
-			   struct drm_dp_mst_topology_state *mst_state,
-			   const struct drm_dp_mst_atomic_payload *old_payload,
-			   struct drm_dp_mst_atomic_payload *new_payload)
+void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
+				 struct drm_dp_mst_topology_state *mst_state,
+				 struct drm_dp_mst_atomic_payload *payload)
 {
-	struct drm_dp_mst_atomic_payload *pos;
+	/* Remove remote payload allocation */
 	bool send_remove = false;
 
-	/* We failed to make the payload, so nothing to do */
-	if (new_payload->vc_start_slot == -1)
-		return;
-
 	mutex_lock(&mgr->lock);
-	send_remove = drm_dp_mst_port_downstream_of_branch(new_payload->port, mgr->mst_primary);
+	send_remove = drm_dp_mst_port_downstream_of_branch(payload->port, mgr->mst_primary);
 	mutex_unlock(&mgr->lock);
 
 	if (send_remove)
-		drm_dp_destroy_payload_step1(mgr, mst_state, new_payload);
+		drm_dp_destroy_payload_at_remote_and_dfp(mgr, mst_state, payload);
 	else
 		drm_dbg_kms(mgr->dev, "Payload for VCPI %d not in topology, not sending remove\n",
-			    new_payload->vcpi);
+			    payload->vcpi);
+
+	payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_LOCAL;
+}
+EXPORT_SYMBOL(drm_dp_remove_payload_part1);
 
+/**
+ * drm_dp_remove_payload_part2() - Remove an MST payload locally
+ * @mgr: Manager to use.
+ * @mst_state: The MST atomic state
+ * @old_payload: The payload with its old state
+ * @new_payload: The payload with its latest state
+ *
+ * Updates the starting time slots of all other payloads which would have been shifted towards
+ * the start of the payload ID table as a result of removing a payload. Driver should call this
+ * function whenever it removes a payload in its HW. It's independent to the result of payload
+ * allocation/deallocation at branch devices along the virtual channel.
+ */
+void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
+				 struct drm_dp_mst_topology_state *mst_state,
+				 const struct drm_dp_mst_atomic_payload *old_payload,
+				 struct drm_dp_mst_atomic_payload *new_payload)
+{
+	struct drm_dp_mst_atomic_payload *pos;
+
+	/* Remove local payload allocation */
 	list_for_each_entry(pos, &mst_state->payloads, next) {
 		if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)
 			pos->vc_start_slot -= old_payload->time_slots;
@@ -3382,9 +3409,10 @@ void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr,
 
 	if (new_payload->delete)
 		drm_dp_mst_put_port_malloc(new_payload->port);
-}
-EXPORT_SYMBOL(drm_dp_remove_payload);
 
+	new_payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
+}
+EXPORT_SYMBOL(drm_dp_remove_payload_part2);
 /**
  * drm_dp_add_payload_part2() - Execute payload update part 2
  * @mgr: Manager to use.
@@ -3403,17 +3431,19 @@ int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
 	int ret = 0;
 
 	/* Skip failed payloads */
-	if (payload->vc_start_slot == -1) {
-		drm_dbg_kms(mgr->dev, "Part 1 of payload creation for %s failed, skipping part 2\n",
+	if (payload->payload_allocation_status != DRM_DP_MST_PAYLOAD_ALLOCATION_DFP) {
+		drm_dbg_kms(state->dev, "Part 1 of payload creation for %s failed, skipping part 2\n",
 			    payload->port->connector->name);
 		return -EIO;
 	}
 
-	ret = drm_dp_create_payload_step2(mgr, payload);
-	if (ret < 0) {
+	/* Allocate payload to remote end */
+	ret = drm_dp_create_payload_to_remote(mgr, payload);
+	if (ret < 0)
 		drm_err(mgr->dev, "Step 2 of creating MST payload for %p failed: %d\n",
 			payload->port, ret);
-	}
+	else
+		payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_REMOTE;
 
 	return ret;
 }
@@ -4324,6 +4354,7 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state,
 		drm_dp_mst_get_port_malloc(port);
 		payload->port = port;
 		payload->vc_start_slot = -1;
+		payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
 		list_add(&payload->next, &topology_state->payloads);
 	}
 	payload->time_slots = req_slots;
@@ -4493,7 +4524,7 @@ void drm_dp_mst_atomic_wait_for_dependencies(struct drm_atomic_state *state)
 		}
 
 		/* Now that previous state is committed, it's safe to copy over the start slot
-		 * assignments
+		 * and allocation status assignments
 		 */
 		list_for_each_entry(old_payload, &old_mst_state->payloads, next) {
 			if (old_payload->delete)
@@ -4502,6 +4533,8 @@ void drm_dp_mst_atomic_wait_for_dependencies(struct drm_atomic_state *state)
 			new_payload = drm_atomic_get_mst_payload_state(new_mst_state,
 								       old_payload->port);
 			new_payload->vc_start_slot = old_payload->vc_start_slot;
+			new_payload->payload_allocation_status =
+							old_payload->payload_allocation_status;
 		}
 	}
 }
@@ -4818,6 +4851,13 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
 	struct drm_dp_mst_atomic_payload *payload;
 	int i, ret;
 
+	static const char *const status[] = {
+		"None",
+		"Local",
+		"DFP",
+		"Remote",
+	};
+
 	mutex_lock(&mgr->lock);
 	if (mgr->mst_primary)
 		drm_dp_mst_dump_mstb(m, mgr->mst_primary);
@@ -4834,7 +4874,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
 	seq_printf(m, "payload_mask: %x, max_payloads: %d, start_slot: %u, pbn_div: %d\n",
 		   state->payload_mask, mgr->max_payloads, state->start_slot, state->pbn_div);
 
-	seq_printf(m, "\n| idx | port | vcpi | slots | pbn | dsc |     sink name     |\n");
+	seq_printf(m, "\n| idx | port | vcpi | slots | pbn | dsc | status |     sink name     |\n");
 	for (i = 0; i < mgr->max_payloads; i++) {
 		list_for_each_entry(payload, &state->payloads, next) {
 			char name[14];
@@ -4843,7 +4883,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
 				continue;
 
 			fetch_monitor_name(mgr, payload->port, name, sizeof(name));
-			seq_printf(m, " %5d %6d %6d %02d - %02d %5d %5s %19s\n",
+			seq_printf(m, " %5d %6d %6d %02d - %02d %5d %5s %8s %19s\n",
 				   i,
 				   payload->port->port_num,
 				   payload->vcpi,
@@ -4851,6 +4891,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
 				   payload->vc_start_slot + payload->time_slots - 1,
 				   payload->pbn,
 				   payload->dsc_enabled ? "Y" : "N",
+				   status[payload->payload_allocation_status],
 				   (*name != 0) ? name : "Unknown");
 		}
 	}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index e3f176a093d2..5f73cdabe7a1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -557,12 +557,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 	struct intel_dp *intel_dp = &dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
-	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
 	struct drm_dp_mst_topology_state *new_mst_state =
 		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
-	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
 	struct drm_dp_mst_atomic_payload *new_payload =
 		drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
@@ -572,8 +568,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 
 	intel_hdcp_disable(intel_mst->connector);
 
-	drm_dp_remove_payload(&intel_dp->mst_mgr, new_mst_state,
-			      old_payload, new_payload);
+	drm_dp_remove_payload_part1(&intel_dp->mst_mgr, new_mst_state, new_payload);
 
 	intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
 }
@@ -588,6 +583,14 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 	struct intel_dp *intel_dp = &dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
+	struct drm_dp_mst_topology_state *old_mst_state =
+		drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
+	struct drm_dp_mst_topology_state *new_mst_state =
+		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
+	const struct drm_dp_mst_atomic_payload *old_payload =
+		drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
+	struct drm_dp_mst_atomic_payload *new_payload =
+		drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	bool last_mst_stream;
 
@@ -608,6 +611,9 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 
 	wait_for_act_sent(encoder, old_crtc_state);
 
+	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state,
+				    old_payload, new_payload);
+
 	intel_ddi_disable_transcoder_func(old_crtc_state);
 
 	if (DISPLAY_VER(dev_priv) >= 9)
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 4e7c9c353c51..6f1b7fcb98e6 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -882,21 +882,26 @@ struct nouveau_encoder *nv50_real_outp(struct drm_encoder *encoder)
 
 static void
 nv50_msto_cleanup(struct drm_atomic_state *state,
-		  struct drm_dp_mst_topology_state *mst_state,
+		  struct drm_dp_mst_topology_state *new_mst_state,
 		  struct drm_dp_mst_topology_mgr *mgr,
 		  struct nv50_msto *msto)
 {
 	struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
-	struct drm_dp_mst_atomic_payload *payload =
-		drm_atomic_get_mst_payload_state(mst_state, msto->mstc->port);
+	struct drm_dp_mst_atomic_payload *new_payload =
+		drm_atomic_get_mst_payload_state(new_mst_state, msto->mstc->port);
+	struct drm_dp_mst_topology_state *old_mst_state =
+		drm_atomic_get_old_mst_topology_state(state, mgr);
+	const struct drm_dp_mst_atomic_payload *old_payload =
+		drm_atomic_get_mst_payload_state(old_mst_state, msto->mstc->port);
 
 	NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
 
 	if (msto->disabled) {
 		msto->mstc = NULL;
 		msto->disabled = false;
+		drm_dp_remove_payload_part2(mgr, new_mst_state, old_payload, new_payload);
 	} else if (msto->enabled) {
-		drm_dp_add_payload_part2(mgr, state, payload);
+		drm_dp_add_payload_part2(mgr, state, new_payload);
 		msto->enabled = false;
 	}
 }
@@ -922,7 +927,7 @@ nv50_msto_prepare(struct drm_atomic_state *state,
 
 	// TODO: Figure out if we want to do a better job of handling VCPI allocation failures here?
 	if (msto->disabled) {
-		drm_dp_remove_payload(mgr, mst_state, old_payload, payload);
+		drm_dp_remove_payload_part1(mgr, mst_state, payload);
 
 		nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index, 0, 0, 0, 0);
 	} else {
diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
index ed5c9660563c..4429d3b1745b 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -46,6 +46,13 @@ struct drm_dp_mst_topology_ref_history {
 };
 #endif /* IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS) */
 
+enum drm_dp_mst_payload_allocation {
+	DRM_DP_MST_PAYLOAD_ALLOCATION_NONE,
+	DRM_DP_MST_PAYLOAD_ALLOCATION_LOCAL,
+	DRM_DP_MST_PAYLOAD_ALLOCATION_DFP,
+	DRM_DP_MST_PAYLOAD_ALLOCATION_REMOTE,
+};
+
 struct drm_dp_mst_branch;
 
 /**
@@ -537,7 +544,7 @@ struct drm_dp_mst_atomic_payload {
 	 *   drm_dp_mst_atomic_wait_for_dependencies() has been called, which will ensure the
 	 *   previous MST states payload start slots have been copied over to the new state. Note
 	 *   that a new start slot won't be assigned/removed from this payload until
-	 *   drm_dp_add_payload_part1()/drm_dp_remove_payload() have been called.
+	 *   drm_dp_add_payload_part1()/drm_dp_remove_payload_part2() have been called.
 	 * * Acquire the MST modesetting lock, and then wait for any pending MST-related commits to
 	 *   get committed to hardware by calling drm_crtc_commit_wait() on each of the
 	 *   &drm_crtc_commit structs in &drm_dp_mst_topology_state.commit_deps.
@@ -564,6 +571,9 @@ struct drm_dp_mst_atomic_payload {
 	/** @dsc_enabled: Whether or not this payload has DSC enabled */
 	bool dsc_enabled : 1;
 
+	/** @payload_allocation_status: The allocation status of this payload */
+	enum drm_dp_mst_payload_allocation payload_allocation_status;
+
 	/** @next: The list node for this payload */
 	struct list_head next;
 };
@@ -842,10 +852,13 @@ int drm_dp_add_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
 int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
 			     struct drm_atomic_state *state,
 			     struct drm_dp_mst_atomic_payload *payload);
-void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr,
-			   struct drm_dp_mst_topology_state *mst_state,
-			   const struct drm_dp_mst_atomic_payload *old_payload,
-			   struct drm_dp_mst_atomic_payload *new_payload);
+void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
+				 struct drm_dp_mst_topology_state *mst_state,
+				 struct drm_dp_mst_atomic_payload *payload);
+void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
+				 struct drm_dp_mst_topology_state *mst_state,
+				 const struct drm_dp_mst_atomic_payload *old_payload,
+				 struct drm_dp_mst_atomic_payload *new_payload);
 
 int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
 
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement
@ 2023-08-04  6:20   ` Wayne Lin
  0 siblings, 0 replies; 38+ messages in thread
From: Wayne Lin @ 2023-08-04  6:20 UTC (permalink / raw)
  To: dri-devel, amd-gfx
  Cc: jani.nikula, imre.deak, jerry.zuo, Wayne Lin, harry.wentland,
	ville.syrjala

[Why]
Today, the allocation/deallocation steps and status is a bit unclear.

For instance, payload->vc_start_slot = -1 stands for "the failure of
updating DPCD payload ID table" and can also represent as "payload is not
allocated yet". These two cases should be handled differently and hence
better to distinguish them for better understanding.

[How]
Define enumeration - ALLOCATION_LOCAL, ALLOCATION_DFP and ALLOCATION_REMOTE
to distinguish different allocation status. Adjust the code to handle
different status accordingly for better understanding the sequence of
payload allocation and payload removement.

For payload creation, the procedure should look like this:
DRM part 1:
* step 1 - update sw mst mgr variables to add a new payload
* step 2 - add payload at immediate DFP DPCD payload table

Driver:
* Add new payload in HW and sync up with DFP by sending ACT

DRM Part 2:
* Send ALLOCATE_PAYLOAD sideband message to allocate bandwidth along the
  virtual channel.

And as for payload removement, the procedure should look like this:
DRM part 1:
* step 1 - Send ALLOCATE_PAYLOAD sideband message to release bandwidth
           along the virtual channel
* step 2 - Clear payload allocation at immediate DFP DPCD payload table

Driver:
* Remove the payload in HW and sync up with DFP by sending ACT

DRM part 2:
* update sw mst mgr variables to remove the payload

Note that it's fine to fail when communicate with the branch device
connected at immediate downstrean-facing port, but updating variables of
SW mst mgr and HW configuration should be conducted anyway. That's because
it's under commit_tail and we need to complete the HW programming.

Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  20 ++-
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 159 +++++++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  18 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  15 +-
 include/drm/display/drm_dp_mst_helper.h       |  23 ++-
 5 files changed, 152 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index d9a482908380..9ad509279b0a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -219,7 +219,7 @@ static void dm_helpers_construct_old_payload(
 	/* Set correct time_slots/PBN of old payload.
 	 * other fields (delete & dsc_enabled) in
 	 * struct drm_dp_mst_atomic_payload are don't care fields
-	 * while calling drm_dp_remove_payload()
+	 * while calling drm_dp_remove_payload_part2()
 	 */
 	for (i = 0; i < current_link_table.stream_count; i++) {
 		dc_alloc =
@@ -262,13 +262,12 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 
 	mst_mgr = &aconnector->mst_root->mst_mgr;
 	mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
-
-	/* It's OK for this to fail */
 	new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
 
 	if (enable) {
 		target_payload = new_payload;
 
+		/* It's OK for this to fail */
 		drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload);
 	} else {
 		/* construct old payload by VCPI*/
@@ -276,7 +275,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 						new_payload, &old_payload);
 		target_payload = &old_payload;
 
-		drm_dp_remove_payload(mst_mgr, mst_state, &old_payload, new_payload);
+		drm_dp_remove_payload_part1(mst_mgr, mst_state, new_payload);
 	}
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
@@ -342,7 +341,7 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_dp_mst_topology_state *mst_state;
 	struct drm_dp_mst_topology_mgr *mst_mgr;
-	struct drm_dp_mst_atomic_payload *payload;
+	struct drm_dp_mst_atomic_payload *new_payload, *old_payload;
 	enum mst_progress_status set_flag = MST_ALLOCATE_NEW_PAYLOAD;
 	enum mst_progress_status clr_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 	int ret = 0;
@@ -355,15 +354,20 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	mst_mgr = &aconnector->mst_root->mst_mgr;
 	mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
 
-	payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
+	new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
 
 	if (!enable) {
 		set_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 		clr_flag = MST_ALLOCATE_NEW_PAYLOAD;
 	}
 
-	if (enable)
-		ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, payload);
+	if (enable) {
+		ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload);
+	} else {
+		dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
+						 new_payload, old_payload);
+		drm_dp_remove_payload_part2(mst_mgr, mst_state, old_payload, new_payload);
+	}
 
 	if (ret) {
 		amdgpu_dm_set_mst_status(&aconnector->mst_status,
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 4d80426757ab..e04f87ff755a 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3255,15 +3255,15 @@ int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
 }
 EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
 
-static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
-				       struct drm_dp_mst_atomic_payload *payload)
+static int drm_dp_create_payload_at_dfp(struct drm_dp_mst_topology_mgr *mgr,
+					struct drm_dp_mst_atomic_payload *payload)
 {
 	return drm_dp_dpcd_write_payload(mgr, payload->vcpi, payload->vc_start_slot,
 					 payload->time_slots);
 }
 
-static int drm_dp_create_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
-				       struct drm_dp_mst_atomic_payload *payload)
+static int drm_dp_create_payload_to_remote(struct drm_dp_mst_topology_mgr *mgr,
+					   struct drm_dp_mst_atomic_payload *payload)
 {
 	int ret;
 	struct drm_dp_mst_port *port = drm_dp_mst_topology_get_port_validated(mgr, payload->port);
@@ -3276,17 +3276,20 @@ static int drm_dp_create_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
 	return ret;
 }
 
-static int drm_dp_destroy_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
-					struct drm_dp_mst_topology_state *mst_state,
-					struct drm_dp_mst_atomic_payload *payload)
+static void drm_dp_destroy_payload_at_remote_and_dfp(struct drm_dp_mst_topology_mgr *mgr,
+						     struct drm_dp_mst_topology_state *mst_state,
+						     struct drm_dp_mst_atomic_payload *payload)
 {
 	drm_dbg_kms(mgr->dev, "\n");
 
 	/* it's okay for these to fail */
-	drm_dp_payload_send_msg(mgr, payload->port, payload->vcpi, 0);
-	drm_dp_dpcd_write_payload(mgr, payload->vcpi, payload->vc_start_slot, 0);
+	if (payload->payload_allocation_status == DRM_DP_MST_PAYLOAD_ALLOCATION_REMOTE) {
+		drm_dp_payload_send_msg(mgr, payload->port, payload->vcpi, 0);
+		payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_DFP;
+	}
 
-	return 0;
+	if (payload->payload_allocation_status == DRM_DP_MST_PAYLOAD_ALLOCATION_DFP)
+		drm_dp_dpcd_write_payload(mgr, payload->vcpi, payload->vc_start_slot, 0);
 }
 
 /**
@@ -3296,81 +3299,105 @@ static int drm_dp_destroy_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
  * @payload: The payload to write
  *
  * Determines the starting time slot for the given payload, and programs the VCPI for this payload
- * into hardware. After calling this, the driver should generate ACT and payload packets.
+ * into the DPCD of DPRX. After calling this, the driver should generate ACT and payload packets.
  *
- * Returns: 0 on success, error code on failure. In the event that this fails,
- * @payload.vc_start_slot will also be set to -1.
+ * Returns: 0 on success, error code on failure.
  */
 int drm_dp_add_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
 			     struct drm_dp_mst_topology_state *mst_state,
 			     struct drm_dp_mst_atomic_payload *payload)
 {
 	struct drm_dp_mst_port *port;
-	int ret;
+	int ret = 0;
+	bool allocate = true;
+
+	/* Update mst mgr info */
+	if (mgr->payload_count == 0)
+		mgr->next_start_slot = mst_state->start_slot;
+
+	payload->vc_start_slot = mgr->next_start_slot;
+
+	mgr->payload_count++;
+	mgr->next_start_slot += payload->time_slots;
 
+	/* Allocate payload to immediate downstream facing port */
 	port = drm_dp_mst_topology_get_port_validated(mgr, payload->port);
 	if (!port) {
 		drm_dbg_kms(mgr->dev,
-			    "VCPI %d for port %p not in topology, not creating a payload\n",
+			    "VCPI %d for port %p not in topology, not creating a payload to remote\n",
 			    payload->vcpi, payload->port);
-		payload->vc_start_slot = -1;
-		return 0;
+		allocate = false;
 	}
 
-	if (mgr->payload_count == 0)
-		mgr->next_start_slot = mst_state->start_slot;
-
-	payload->vc_start_slot = mgr->next_start_slot;
+	if (allocate) {
+		ret = drm_dp_create_payload_at_dfp(mgr, payload);
+		if (ret < 0)
+			drm_warn(mgr->dev, "Failed to create MST payload for port %p: %d\n",
+				 payload->port, ret);
 
-	ret = drm_dp_create_payload_step1(mgr, payload);
-	drm_dp_mst_topology_put_port(port);
-	if (ret < 0) {
-		drm_warn(mgr->dev, "Failed to create MST payload for port %p: %d\n",
-			 payload->port, ret);
-		payload->vc_start_slot = -1;
-		return ret;
 	}
 
-	mgr->payload_count++;
-	mgr->next_start_slot += payload->time_slots;
+	payload->payload_allocation_status =
+		(!allocate || ret < 0) ? DRM_DP_MST_PAYLOAD_ALLOCATION_LOCAL :
+								DRM_DP_MST_PAYLOAD_ALLOCATION_DFP;
 
-	return 0;
+	drm_dp_mst_topology_put_port(port);
+
+	return ret;
 }
 EXPORT_SYMBOL(drm_dp_add_payload_part1);
 
 /**
- * drm_dp_remove_payload() - Remove an MST payload
+ * drm_dp_remove_payload_part1() - Remove an MST payload along the virtual channel
  * @mgr: Manager to use.
  * @mst_state: The MST atomic state
- * @old_payload: The payload with its old state
- * @new_payload: The payload to write
+ * @payload: The payload to remove
  *
- * Removes a payload from an MST topology if it was successfully assigned a start slot. Also updates
- * the starting time slots of all other payloads which would have been shifted towards the start of
- * the VC table as a result. After calling this, the driver should generate ACT and payload packets.
+ * Removes a payload along the virtual channel if it was successfully allocated.
+ * After calling this, the driver should set HW to generate ACT and then switch to new
+ * payload allocation state.
  */
-void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr,
-			   struct drm_dp_mst_topology_state *mst_state,
-			   const struct drm_dp_mst_atomic_payload *old_payload,
-			   struct drm_dp_mst_atomic_payload *new_payload)
+void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
+				 struct drm_dp_mst_topology_state *mst_state,
+				 struct drm_dp_mst_atomic_payload *payload)
 {
-	struct drm_dp_mst_atomic_payload *pos;
+	/* Remove remote payload allocation */
 	bool send_remove = false;
 
-	/* We failed to make the payload, so nothing to do */
-	if (new_payload->vc_start_slot == -1)
-		return;
-
 	mutex_lock(&mgr->lock);
-	send_remove = drm_dp_mst_port_downstream_of_branch(new_payload->port, mgr->mst_primary);
+	send_remove = drm_dp_mst_port_downstream_of_branch(payload->port, mgr->mst_primary);
 	mutex_unlock(&mgr->lock);
 
 	if (send_remove)
-		drm_dp_destroy_payload_step1(mgr, mst_state, new_payload);
+		drm_dp_destroy_payload_at_remote_and_dfp(mgr, mst_state, payload);
 	else
 		drm_dbg_kms(mgr->dev, "Payload for VCPI %d not in topology, not sending remove\n",
-			    new_payload->vcpi);
+			    payload->vcpi);
+
+	payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_LOCAL;
+}
+EXPORT_SYMBOL(drm_dp_remove_payload_part1);
 
+/**
+ * drm_dp_remove_payload_part2() - Remove an MST payload locally
+ * @mgr: Manager to use.
+ * @mst_state: The MST atomic state
+ * @old_payload: The payload with its old state
+ * @new_payload: The payload with its latest state
+ *
+ * Updates the starting time slots of all other payloads which would have been shifted towards
+ * the start of the payload ID table as a result of removing a payload. Driver should call this
+ * function whenever it removes a payload in its HW. It's independent to the result of payload
+ * allocation/deallocation at branch devices along the virtual channel.
+ */
+void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
+				 struct drm_dp_mst_topology_state *mst_state,
+				 const struct drm_dp_mst_atomic_payload *old_payload,
+				 struct drm_dp_mst_atomic_payload *new_payload)
+{
+	struct drm_dp_mst_atomic_payload *pos;
+
+	/* Remove local payload allocation */
 	list_for_each_entry(pos, &mst_state->payloads, next) {
 		if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)
 			pos->vc_start_slot -= old_payload->time_slots;
@@ -3382,9 +3409,10 @@ void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr,
 
 	if (new_payload->delete)
 		drm_dp_mst_put_port_malloc(new_payload->port);
-}
-EXPORT_SYMBOL(drm_dp_remove_payload);
 
+	new_payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
+}
+EXPORT_SYMBOL(drm_dp_remove_payload_part2);
 /**
  * drm_dp_add_payload_part2() - Execute payload update part 2
  * @mgr: Manager to use.
@@ -3403,17 +3431,19 @@ int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
 	int ret = 0;
 
 	/* Skip failed payloads */
-	if (payload->vc_start_slot == -1) {
-		drm_dbg_kms(mgr->dev, "Part 1 of payload creation for %s failed, skipping part 2\n",
+	if (payload->payload_allocation_status != DRM_DP_MST_PAYLOAD_ALLOCATION_DFP) {
+		drm_dbg_kms(state->dev, "Part 1 of payload creation for %s failed, skipping part 2\n",
 			    payload->port->connector->name);
 		return -EIO;
 	}
 
-	ret = drm_dp_create_payload_step2(mgr, payload);
-	if (ret < 0) {
+	/* Allocate payload to remote end */
+	ret = drm_dp_create_payload_to_remote(mgr, payload);
+	if (ret < 0)
 		drm_err(mgr->dev, "Step 2 of creating MST payload for %p failed: %d\n",
 			payload->port, ret);
-	}
+	else
+		payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_REMOTE;
 
 	return ret;
 }
@@ -4324,6 +4354,7 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state,
 		drm_dp_mst_get_port_malloc(port);
 		payload->port = port;
 		payload->vc_start_slot = -1;
+		payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
 		list_add(&payload->next, &topology_state->payloads);
 	}
 	payload->time_slots = req_slots;
@@ -4493,7 +4524,7 @@ void drm_dp_mst_atomic_wait_for_dependencies(struct drm_atomic_state *state)
 		}
 
 		/* Now that previous state is committed, it's safe to copy over the start slot
-		 * assignments
+		 * and allocation status assignments
 		 */
 		list_for_each_entry(old_payload, &old_mst_state->payloads, next) {
 			if (old_payload->delete)
@@ -4502,6 +4533,8 @@ void drm_dp_mst_atomic_wait_for_dependencies(struct drm_atomic_state *state)
 			new_payload = drm_atomic_get_mst_payload_state(new_mst_state,
 								       old_payload->port);
 			new_payload->vc_start_slot = old_payload->vc_start_slot;
+			new_payload->payload_allocation_status =
+							old_payload->payload_allocation_status;
 		}
 	}
 }
@@ -4818,6 +4851,13 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
 	struct drm_dp_mst_atomic_payload *payload;
 	int i, ret;
 
+	static const char *const status[] = {
+		"None",
+		"Local",
+		"DFP",
+		"Remote",
+	};
+
 	mutex_lock(&mgr->lock);
 	if (mgr->mst_primary)
 		drm_dp_mst_dump_mstb(m, mgr->mst_primary);
@@ -4834,7 +4874,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
 	seq_printf(m, "payload_mask: %x, max_payloads: %d, start_slot: %u, pbn_div: %d\n",
 		   state->payload_mask, mgr->max_payloads, state->start_slot, state->pbn_div);
 
-	seq_printf(m, "\n| idx | port | vcpi | slots | pbn | dsc |     sink name     |\n");
+	seq_printf(m, "\n| idx | port | vcpi | slots | pbn | dsc | status |     sink name     |\n");
 	for (i = 0; i < mgr->max_payloads; i++) {
 		list_for_each_entry(payload, &state->payloads, next) {
 			char name[14];
@@ -4843,7 +4883,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
 				continue;
 
 			fetch_monitor_name(mgr, payload->port, name, sizeof(name));
-			seq_printf(m, " %5d %6d %6d %02d - %02d %5d %5s %19s\n",
+			seq_printf(m, " %5d %6d %6d %02d - %02d %5d %5s %8s %19s\n",
 				   i,
 				   payload->port->port_num,
 				   payload->vcpi,
@@ -4851,6 +4891,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
 				   payload->vc_start_slot + payload->time_slots - 1,
 				   payload->pbn,
 				   payload->dsc_enabled ? "Y" : "N",
+				   status[payload->payload_allocation_status],
 				   (*name != 0) ? name : "Unknown");
 		}
 	}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index e3f176a093d2..5f73cdabe7a1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -557,12 +557,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 	struct intel_dp *intel_dp = &dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
-	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
 	struct drm_dp_mst_topology_state *new_mst_state =
 		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
-	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
 	struct drm_dp_mst_atomic_payload *new_payload =
 		drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
@@ -572,8 +568,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 
 	intel_hdcp_disable(intel_mst->connector);
 
-	drm_dp_remove_payload(&intel_dp->mst_mgr, new_mst_state,
-			      old_payload, new_payload);
+	drm_dp_remove_payload_part1(&intel_dp->mst_mgr, new_mst_state, new_payload);
 
 	intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
 }
@@ -588,6 +583,14 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 	struct intel_dp *intel_dp = &dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
+	struct drm_dp_mst_topology_state *old_mst_state =
+		drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
+	struct drm_dp_mst_topology_state *new_mst_state =
+		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
+	const struct drm_dp_mst_atomic_payload *old_payload =
+		drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
+	struct drm_dp_mst_atomic_payload *new_payload =
+		drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	bool last_mst_stream;
 
@@ -608,6 +611,9 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 
 	wait_for_act_sent(encoder, old_crtc_state);
 
+	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state,
+				    old_payload, new_payload);
+
 	intel_ddi_disable_transcoder_func(old_crtc_state);
 
 	if (DISPLAY_VER(dev_priv) >= 9)
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 4e7c9c353c51..6f1b7fcb98e6 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -882,21 +882,26 @@ struct nouveau_encoder *nv50_real_outp(struct drm_encoder *encoder)
 
 static void
 nv50_msto_cleanup(struct drm_atomic_state *state,
-		  struct drm_dp_mst_topology_state *mst_state,
+		  struct drm_dp_mst_topology_state *new_mst_state,
 		  struct drm_dp_mst_topology_mgr *mgr,
 		  struct nv50_msto *msto)
 {
 	struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
-	struct drm_dp_mst_atomic_payload *payload =
-		drm_atomic_get_mst_payload_state(mst_state, msto->mstc->port);
+	struct drm_dp_mst_atomic_payload *new_payload =
+		drm_atomic_get_mst_payload_state(new_mst_state, msto->mstc->port);
+	struct drm_dp_mst_topology_state *old_mst_state =
+		drm_atomic_get_old_mst_topology_state(state, mgr);
+	const struct drm_dp_mst_atomic_payload *old_payload =
+		drm_atomic_get_mst_payload_state(old_mst_state, msto->mstc->port);
 
 	NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
 
 	if (msto->disabled) {
 		msto->mstc = NULL;
 		msto->disabled = false;
+		drm_dp_remove_payload_part2(mgr, new_mst_state, old_payload, new_payload);
 	} else if (msto->enabled) {
-		drm_dp_add_payload_part2(mgr, state, payload);
+		drm_dp_add_payload_part2(mgr, state, new_payload);
 		msto->enabled = false;
 	}
 }
@@ -922,7 +927,7 @@ nv50_msto_prepare(struct drm_atomic_state *state,
 
 	// TODO: Figure out if we want to do a better job of handling VCPI allocation failures here?
 	if (msto->disabled) {
-		drm_dp_remove_payload(mgr, mst_state, old_payload, payload);
+		drm_dp_remove_payload_part1(mgr, mst_state, payload);
 
 		nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index, 0, 0, 0, 0);
 	} else {
diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
index ed5c9660563c..4429d3b1745b 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -46,6 +46,13 @@ struct drm_dp_mst_topology_ref_history {
 };
 #endif /* IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS) */
 
+enum drm_dp_mst_payload_allocation {
+	DRM_DP_MST_PAYLOAD_ALLOCATION_NONE,
+	DRM_DP_MST_PAYLOAD_ALLOCATION_LOCAL,
+	DRM_DP_MST_PAYLOAD_ALLOCATION_DFP,
+	DRM_DP_MST_PAYLOAD_ALLOCATION_REMOTE,
+};
+
 struct drm_dp_mst_branch;
 
 /**
@@ -537,7 +544,7 @@ struct drm_dp_mst_atomic_payload {
 	 *   drm_dp_mst_atomic_wait_for_dependencies() has been called, which will ensure the
 	 *   previous MST states payload start slots have been copied over to the new state. Note
 	 *   that a new start slot won't be assigned/removed from this payload until
-	 *   drm_dp_add_payload_part1()/drm_dp_remove_payload() have been called.
+	 *   drm_dp_add_payload_part1()/drm_dp_remove_payload_part2() have been called.
 	 * * Acquire the MST modesetting lock, and then wait for any pending MST-related commits to
 	 *   get committed to hardware by calling drm_crtc_commit_wait() on each of the
 	 *   &drm_crtc_commit structs in &drm_dp_mst_topology_state.commit_deps.
@@ -564,6 +571,9 @@ struct drm_dp_mst_atomic_payload {
 	/** @dsc_enabled: Whether or not this payload has DSC enabled */
 	bool dsc_enabled : 1;
 
+	/** @payload_allocation_status: The allocation status of this payload */
+	enum drm_dp_mst_payload_allocation payload_allocation_status;
+
 	/** @next: The list node for this payload */
 	struct list_head next;
 };
@@ -842,10 +852,13 @@ int drm_dp_add_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
 int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
 			     struct drm_atomic_state *state,
 			     struct drm_dp_mst_atomic_payload *payload);
-void drm_dp_remove_payload(struct drm_dp_mst_topology_mgr *mgr,
-			   struct drm_dp_mst_topology_state *mst_state,
-			   const struct drm_dp_mst_atomic_payload *old_payload,
-			   struct drm_dp_mst_atomic_payload *new_payload);
+void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
+				 struct drm_dp_mst_topology_state *mst_state,
+				 struct drm_dp_mst_atomic_payload *payload);
+void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
+				 struct drm_dp_mst_topology_state *mst_state,
+				 const struct drm_dp_mst_atomic_payload *old_payload,
+				 struct drm_dp_mst_atomic_payload *new_payload);
 
 int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
 
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-08-04  6:20 ` Wayne Lin
@ 2023-08-04  6:20   ` Wayne Lin
  -1 siblings, 0 replies; 38+ messages in thread
From: Wayne Lin @ 2023-08-04  6:20 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: jani.nikula, jerry.zuo, Wayne Lin

[Why]
Now in drm_dp_remove_payload_part2(), it utilizes the time slot number
of the payload in old state to represent the one in the payload table
at the moment.

It would be better to clarify the idea by using the latest allocated
time slot number for the port at the moment instead and which info is
already included in new mst_state. By this, we can also remove redundant
workaround for amdgpu driver.

[How]
Remove "old_payload" input of drm_dp_remove_payload_part2() and get the
latest number of allocated time slot for the port from new mst_state
instead.

Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 70 ++++---------------
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 32 ++++++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  7 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  6 +-
 include/drm/display/drm_dp_mst_helper.h       |  9 ++-
 5 files changed, 40 insertions(+), 84 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 9ad509279b0a..e852da686c26 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -203,40 +203,6 @@ void dm_helpers_dp_update_branch_info(
 	const struct dc_link *link)
 {}
 
-static void dm_helpers_construct_old_payload(
-			struct dc_link *link,
-			int pbn_per_slot,
-			struct drm_dp_mst_atomic_payload *new_payload,
-			struct drm_dp_mst_atomic_payload *old_payload)
-{
-	struct link_mst_stream_allocation_table current_link_table =
-									link->mst_stream_alloc_table;
-	struct link_mst_stream_allocation *dc_alloc;
-	int i;
-
-	*old_payload = *new_payload;
-
-	/* Set correct time_slots/PBN of old payload.
-	 * other fields (delete & dsc_enabled) in
-	 * struct drm_dp_mst_atomic_payload are don't care fields
-	 * while calling drm_dp_remove_payload_part2()
-	 */
-	for (i = 0; i < current_link_table.stream_count; i++) {
-		dc_alloc =
-			&current_link_table.stream_allocations[i];
-
-		if (dc_alloc->vcp_id == new_payload->vcpi) {
-			old_payload->time_slots = dc_alloc->slot_count;
-			old_payload->pbn = dc_alloc->slot_count * pbn_per_slot;
-			break;
-		}
-	}
-
-	/* make sure there is an old payload*/
-	ASSERT(i != current_link_table.stream_count);
-
-}
-
 /*
  * Writes payload allocation table in immediate downstream device.
  */
@@ -248,7 +214,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 {
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_dp_mst_topology_state *mst_state;
-	struct drm_dp_mst_atomic_payload *target_payload, *new_payload, old_payload;
+	struct drm_dp_mst_atomic_payload *payload;
 	struct drm_dp_mst_topology_mgr *mst_mgr;
 
 	aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
@@ -262,27 +228,20 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 
 	mst_mgr = &aconnector->mst_root->mst_mgr;
 	mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
-	new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
-
-	if (enable) {
-		target_payload = new_payload;
+	payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
 
+	if (enable)
 		/* It's OK for this to fail */
-		drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload);
-	} else {
-		/* construct old payload by VCPI*/
-		dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
-						new_payload, &old_payload);
-		target_payload = &old_payload;
+		drm_dp_add_payload_part1(mst_mgr, mst_state, payload);
+	else
 
-		drm_dp_remove_payload_part1(mst_mgr, mst_state, new_payload);
-	}
+		drm_dp_remove_payload_part1(mst_mgr, mst_state, payload);
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
 	 * AUX message. The sequence is slot 1-63 allocated sequence for each
 	 * stream. AMD ASIC stream slot allocation should follow the same
 	 * sequence. copy DRM MST allocation to dc */
-	fill_dc_mst_payload_table_from_drm(stream->link, enable, target_payload, proposed_table);
+	fill_dc_mst_payload_table_from_drm(stream->link, enable, payload, proposed_table);
 
 	return true;
 }
@@ -341,7 +300,7 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_dp_mst_topology_state *mst_state;
 	struct drm_dp_mst_topology_mgr *mst_mgr;
-	struct drm_dp_mst_atomic_payload *new_payload, *old_payload;
+	struct drm_dp_mst_atomic_payload *payload;
 	enum mst_progress_status set_flag = MST_ALLOCATE_NEW_PAYLOAD;
 	enum mst_progress_status clr_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 	int ret = 0;
@@ -354,20 +313,17 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	mst_mgr = &aconnector->mst_root->mst_mgr;
 	mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
 
-	new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
+	payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
 
 	if (!enable) {
 		set_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 		clr_flag = MST_ALLOCATE_NEW_PAYLOAD;
 	}
 
-	if (enable) {
-		ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload);
-	} else {
-		dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
-						 new_payload, old_payload);
-		drm_dp_remove_payload_part2(mst_mgr, mst_state, old_payload, new_payload);
-	}
+	if (enable)
+		ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, payload);
+	else
+		drm_dp_remove_payload_part2(mst_mgr, mst_state, payload);
 
 	if (ret) {
 		amdgpu_dm_set_mst_status(&aconnector->mst_status,
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index e04f87ff755a..4270178f95f6 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3382,8 +3382,7 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part1);
  * drm_dp_remove_payload_part2() - Remove an MST payload locally
  * @mgr: Manager to use.
  * @mst_state: The MST atomic state
- * @old_payload: The payload with its old state
- * @new_payload: The payload with its latest state
+ * @payload: The payload with its latest state
  *
  * Updates the starting time slots of all other payloads which would have been shifted towards
  * the start of the payload ID table as a result of removing a payload. Driver should call this
@@ -3392,25 +3391,36 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part1);
  */
 void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_dp_mst_topology_state *mst_state,
-				 const struct drm_dp_mst_atomic_payload *old_payload,
-				 struct drm_dp_mst_atomic_payload *new_payload)
+				 struct drm_dp_mst_atomic_payload *payload)
 {
 	struct drm_dp_mst_atomic_payload *pos;
+	u8 time_slots_to_remove;
+	u8 next_payload_vc_start = mgr->next_start_slot;
+
+	/* Find the current allocated time slot number of the payload */
+	list_for_each_entry(pos, &mst_state->payloads, next) {
+		if (pos != payload &&
+		    pos->vc_start_slot > payload->vc_start_slot &&
+		    pos->vc_start_slot < next_payload_vc_start)
+			next_payload_vc_start = pos->vc_start_slot;
+	}
+
+	time_slots_to_remove = next_payload_vc_start - payload->vc_start_slot;
 
 	/* Remove local payload allocation */
 	list_for_each_entry(pos, &mst_state->payloads, next) {
-		if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)
-			pos->vc_start_slot -= old_payload->time_slots;
+		if (pos != payload && pos->vc_start_slot > payload->vc_start_slot)
+			pos->vc_start_slot -= time_slots_to_remove;
 	}
-	new_payload->vc_start_slot = -1;
+	payload->vc_start_slot = -1;
 
 	mgr->payload_count--;
-	mgr->next_start_slot -= old_payload->time_slots;
+	mgr->next_start_slot -= time_slots_to_remove;
 
-	if (new_payload->delete)
-		drm_dp_mst_put_port_malloc(new_payload->port);
+	if (payload->delete)
+		drm_dp_mst_put_port_malloc(payload->port);
 
-	new_payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
+	payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
 }
 EXPORT_SYMBOL(drm_dp_remove_payload_part2);
 /**
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 5f73cdabe7a1..91750c1dfc48 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -583,12 +583,8 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 	struct intel_dp *intel_dp = &dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
-	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
 	struct drm_dp_mst_topology_state *new_mst_state =
 		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
-	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
 	struct drm_dp_mst_atomic_payload *new_payload =
 		drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -611,8 +607,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 
 	wait_for_act_sent(encoder, old_crtc_state);
 
-	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state,
-				    old_payload, new_payload);
+	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state, new_payload);
 
 	intel_ddi_disable_transcoder_func(old_crtc_state);
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 6f1b7fcb98e6..63e2a286fffc 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -889,17 +889,13 @@ nv50_msto_cleanup(struct drm_atomic_state *state,
 	struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
 	struct drm_dp_mst_atomic_payload *new_payload =
 		drm_atomic_get_mst_payload_state(new_mst_state, msto->mstc->port);
-	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(state, mgr);
-	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, msto->mstc->port);
 
 	NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
 
 	if (msto->disabled) {
 		msto->mstc = NULL;
 		msto->disabled = false;
-		drm_dp_remove_payload_part2(mgr, new_mst_state, old_payload, new_payload);
+		drm_dp_remove_payload_part2(mgr, new_mst_state, new_payload);
 	} else if (msto->enabled) {
 		drm_dp_add_payload_part2(mgr, state, new_payload);
 		msto->enabled = false;
diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
index 4429d3b1745b..3f8ad28c77b1 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -853,12 +853,11 @@ int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
 			     struct drm_atomic_state *state,
 			     struct drm_dp_mst_atomic_payload *payload);
 void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
-				 struct drm_dp_mst_topology_state *mst_state,
-				 struct drm_dp_mst_atomic_payload *payload);
+				  struct drm_dp_mst_topology_state *mst_state,
+				  struct drm_dp_mst_atomic_payload *payload);
 void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
-				 struct drm_dp_mst_topology_state *mst_state,
-				 const struct drm_dp_mst_atomic_payload *old_payload,
-				 struct drm_dp_mst_atomic_payload *new_payload);
+				  struct drm_dp_mst_topology_state *mst_state,
+				  struct drm_dp_mst_atomic_payload *payload);
 
 int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
 
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-08-04  6:20   ` Wayne Lin
  0 siblings, 0 replies; 38+ messages in thread
From: Wayne Lin @ 2023-08-04  6:20 UTC (permalink / raw)
  To: dri-devel, amd-gfx
  Cc: jani.nikula, imre.deak, jerry.zuo, Wayne Lin, harry.wentland,
	ville.syrjala

[Why]
Now in drm_dp_remove_payload_part2(), it utilizes the time slot number
of the payload in old state to represent the one in the payload table
at the moment.

It would be better to clarify the idea by using the latest allocated
time slot number for the port at the moment instead and which info is
already included in new mst_state. By this, we can also remove redundant
workaround for amdgpu driver.

[How]
Remove "old_payload" input of drm_dp_remove_payload_part2() and get the
latest number of allocated time slot for the port from new mst_state
instead.

Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 70 ++++---------------
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 32 ++++++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  7 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  6 +-
 include/drm/display/drm_dp_mst_helper.h       |  9 ++-
 5 files changed, 40 insertions(+), 84 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 9ad509279b0a..e852da686c26 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -203,40 +203,6 @@ void dm_helpers_dp_update_branch_info(
 	const struct dc_link *link)
 {}
 
-static void dm_helpers_construct_old_payload(
-			struct dc_link *link,
-			int pbn_per_slot,
-			struct drm_dp_mst_atomic_payload *new_payload,
-			struct drm_dp_mst_atomic_payload *old_payload)
-{
-	struct link_mst_stream_allocation_table current_link_table =
-									link->mst_stream_alloc_table;
-	struct link_mst_stream_allocation *dc_alloc;
-	int i;
-
-	*old_payload = *new_payload;
-
-	/* Set correct time_slots/PBN of old payload.
-	 * other fields (delete & dsc_enabled) in
-	 * struct drm_dp_mst_atomic_payload are don't care fields
-	 * while calling drm_dp_remove_payload_part2()
-	 */
-	for (i = 0; i < current_link_table.stream_count; i++) {
-		dc_alloc =
-			&current_link_table.stream_allocations[i];
-
-		if (dc_alloc->vcp_id == new_payload->vcpi) {
-			old_payload->time_slots = dc_alloc->slot_count;
-			old_payload->pbn = dc_alloc->slot_count * pbn_per_slot;
-			break;
-		}
-	}
-
-	/* make sure there is an old payload*/
-	ASSERT(i != current_link_table.stream_count);
-
-}
-
 /*
  * Writes payload allocation table in immediate downstream device.
  */
@@ -248,7 +214,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 {
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_dp_mst_topology_state *mst_state;
-	struct drm_dp_mst_atomic_payload *target_payload, *new_payload, old_payload;
+	struct drm_dp_mst_atomic_payload *payload;
 	struct drm_dp_mst_topology_mgr *mst_mgr;
 
 	aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
@@ -262,27 +228,20 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 
 	mst_mgr = &aconnector->mst_root->mst_mgr;
 	mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
-	new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
-
-	if (enable) {
-		target_payload = new_payload;
+	payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
 
+	if (enable)
 		/* It's OK for this to fail */
-		drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload);
-	} else {
-		/* construct old payload by VCPI*/
-		dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
-						new_payload, &old_payload);
-		target_payload = &old_payload;
+		drm_dp_add_payload_part1(mst_mgr, mst_state, payload);
+	else
 
-		drm_dp_remove_payload_part1(mst_mgr, mst_state, new_payload);
-	}
+		drm_dp_remove_payload_part1(mst_mgr, mst_state, payload);
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
 	 * AUX message. The sequence is slot 1-63 allocated sequence for each
 	 * stream. AMD ASIC stream slot allocation should follow the same
 	 * sequence. copy DRM MST allocation to dc */
-	fill_dc_mst_payload_table_from_drm(stream->link, enable, target_payload, proposed_table);
+	fill_dc_mst_payload_table_from_drm(stream->link, enable, payload, proposed_table);
 
 	return true;
 }
@@ -341,7 +300,7 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_dp_mst_topology_state *mst_state;
 	struct drm_dp_mst_topology_mgr *mst_mgr;
-	struct drm_dp_mst_atomic_payload *new_payload, *old_payload;
+	struct drm_dp_mst_atomic_payload *payload;
 	enum mst_progress_status set_flag = MST_ALLOCATE_NEW_PAYLOAD;
 	enum mst_progress_status clr_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 	int ret = 0;
@@ -354,20 +313,17 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	mst_mgr = &aconnector->mst_root->mst_mgr;
 	mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
 
-	new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
+	payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
 
 	if (!enable) {
 		set_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 		clr_flag = MST_ALLOCATE_NEW_PAYLOAD;
 	}
 
-	if (enable) {
-		ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload);
-	} else {
-		dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
-						 new_payload, old_payload);
-		drm_dp_remove_payload_part2(mst_mgr, mst_state, old_payload, new_payload);
-	}
+	if (enable)
+		ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, payload);
+	else
+		drm_dp_remove_payload_part2(mst_mgr, mst_state, payload);
 
 	if (ret) {
 		amdgpu_dm_set_mst_status(&aconnector->mst_status,
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index e04f87ff755a..4270178f95f6 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3382,8 +3382,7 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part1);
  * drm_dp_remove_payload_part2() - Remove an MST payload locally
  * @mgr: Manager to use.
  * @mst_state: The MST atomic state
- * @old_payload: The payload with its old state
- * @new_payload: The payload with its latest state
+ * @payload: The payload with its latest state
  *
  * Updates the starting time slots of all other payloads which would have been shifted towards
  * the start of the payload ID table as a result of removing a payload. Driver should call this
@@ -3392,25 +3391,36 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part1);
  */
 void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_dp_mst_topology_state *mst_state,
-				 const struct drm_dp_mst_atomic_payload *old_payload,
-				 struct drm_dp_mst_atomic_payload *new_payload)
+				 struct drm_dp_mst_atomic_payload *payload)
 {
 	struct drm_dp_mst_atomic_payload *pos;
+	u8 time_slots_to_remove;
+	u8 next_payload_vc_start = mgr->next_start_slot;
+
+	/* Find the current allocated time slot number of the payload */
+	list_for_each_entry(pos, &mst_state->payloads, next) {
+		if (pos != payload &&
+		    pos->vc_start_slot > payload->vc_start_slot &&
+		    pos->vc_start_slot < next_payload_vc_start)
+			next_payload_vc_start = pos->vc_start_slot;
+	}
+
+	time_slots_to_remove = next_payload_vc_start - payload->vc_start_slot;
 
 	/* Remove local payload allocation */
 	list_for_each_entry(pos, &mst_state->payloads, next) {
-		if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)
-			pos->vc_start_slot -= old_payload->time_slots;
+		if (pos != payload && pos->vc_start_slot > payload->vc_start_slot)
+			pos->vc_start_slot -= time_slots_to_remove;
 	}
-	new_payload->vc_start_slot = -1;
+	payload->vc_start_slot = -1;
 
 	mgr->payload_count--;
-	mgr->next_start_slot -= old_payload->time_slots;
+	mgr->next_start_slot -= time_slots_to_remove;
 
-	if (new_payload->delete)
-		drm_dp_mst_put_port_malloc(new_payload->port);
+	if (payload->delete)
+		drm_dp_mst_put_port_malloc(payload->port);
 
-	new_payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
+	payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
 }
 EXPORT_SYMBOL(drm_dp_remove_payload_part2);
 /**
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 5f73cdabe7a1..91750c1dfc48 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -583,12 +583,8 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 	struct intel_dp *intel_dp = &dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
-	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
 	struct drm_dp_mst_topology_state *new_mst_state =
 		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
-	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
 	struct drm_dp_mst_atomic_payload *new_payload =
 		drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -611,8 +607,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 
 	wait_for_act_sent(encoder, old_crtc_state);
 
-	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state,
-				    old_payload, new_payload);
+	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state, new_payload);
 
 	intel_ddi_disable_transcoder_func(old_crtc_state);
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 6f1b7fcb98e6..63e2a286fffc 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -889,17 +889,13 @@ nv50_msto_cleanup(struct drm_atomic_state *state,
 	struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
 	struct drm_dp_mst_atomic_payload *new_payload =
 		drm_atomic_get_mst_payload_state(new_mst_state, msto->mstc->port);
-	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(state, mgr);
-	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, msto->mstc->port);
 
 	NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
 
 	if (msto->disabled) {
 		msto->mstc = NULL;
 		msto->disabled = false;
-		drm_dp_remove_payload_part2(mgr, new_mst_state, old_payload, new_payload);
+		drm_dp_remove_payload_part2(mgr, new_mst_state, new_payload);
 	} else if (msto->enabled) {
 		drm_dp_add_payload_part2(mgr, state, new_payload);
 		msto->enabled = false;
diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
index 4429d3b1745b..3f8ad28c77b1 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -853,12 +853,11 @@ int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
 			     struct drm_atomic_state *state,
 			     struct drm_dp_mst_atomic_payload *payload);
 void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
-				 struct drm_dp_mst_topology_state *mst_state,
-				 struct drm_dp_mst_atomic_payload *payload);
+				  struct drm_dp_mst_topology_state *mst_state,
+				  struct drm_dp_mst_atomic_payload *payload);
 void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
-				 struct drm_dp_mst_topology_state *mst_state,
-				 const struct drm_dp_mst_atomic_payload *old_payload,
-				 struct drm_dp_mst_atomic_payload *new_payload);
+				  struct drm_dp_mst_topology_state *mst_state,
+				  struct drm_dp_mst_atomic_payload *payload);
 
 int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
 
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement
  2023-08-04  6:20   ` Wayne Lin
@ 2023-08-04  9:19     ` kernel test robot
  -1 siblings, 0 replies; 38+ messages in thread
From: kernel test robot @ 2023-08-04  9:19 UTC (permalink / raw)
  To: Wayne Lin, dri-devel, amd-gfx
  Cc: oe-kbuild-all, jani.nikula, jerry.zuo, Wayne Lin

Hi Wayne,

kernel test robot noticed the following build warnings:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on drm-intel/for-linux-next-fixes drm/drm-next linus/master v6.5-rc4 next-20230804]
[cannot apply to drm-intel/for-linux-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Wayne-Lin/drm-mst-delete-unnecessary-case-in-drm_dp_add_payload_part2/20230804-142405
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:    https://lore.kernel.org/r/20230804062029.5686-3-Wayne.Lin%40amd.com
patch subject: [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement
config: microblaze-randconfig-r021-20230731 (https://download.01.org/0day-ci/archive/20230804/202308041635.WkgWWX5r-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230804/202308041635.WkgWWX5r-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308041635.WkgWWX5r-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/nouveau/dispnv50/disp.c: In function 'nv50_msto_prepare':
>> drivers/gpu/drm/nouveau/dispnv50/disp.c:919:53: warning: variable 'old_payload' set but not used [-Wunused-but-set-variable]
     919 |         struct drm_dp_mst_atomic_payload *payload, *old_payload;
         |                                                     ^~~~~~~~~~~


vim +/old_payload +919 drivers/gpu/drm/nouveau/dispnv50/disp.c

f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  908  
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  909  static void
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  910  nv50_msto_prepare(struct drm_atomic_state *state,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  911  		  struct drm_dp_mst_topology_state *mst_state,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  912  		  struct drm_dp_mst_topology_mgr *mgr,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  913  		  struct nv50_msto *msto)
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  914  {
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  915  	struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  916  	struct nv50_mstc *mstc = msto->mstc;
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  917  	struct nv50_mstm *mstm = mstc->mstm;
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  918  	struct drm_dp_mst_topology_state *old_mst_state;
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13 @919  	struct drm_dp_mst_atomic_payload *payload, *old_payload;
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  920  
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  921  	NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  922  
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  923  	old_mst_state = drm_atomic_get_old_mst_topology_state(state, mgr);
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  924  
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  925  	payload = drm_atomic_get_mst_payload_state(mst_state, mstc->port);
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  926  	old_payload = drm_atomic_get_mst_payload_state(old_mst_state, mstc->port);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  927  
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  928  	// TODO: Figure out if we want to do a better job of handling VCPI allocation failures here?
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  929  	if (msto->disabled) {
c9e8c7f37133c0 drivers/gpu/drm/nouveau/dispnv50/disp.c Wayne Lin  2023-08-04  930  		drm_dp_remove_payload_part1(mgr, mst_state, payload);
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  931  
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  932  		nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index, 0, 0, 0, 0);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  933  	} else {
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  934  		if (msto->enabled)
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  935  			drm_dp_add_payload_part1(mgr, mst_state, payload);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  936  
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  937  		nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index,
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  938  				      payload->vc_start_slot, payload->time_slots,
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  939  				      payload->pbn, payload->time_slots * mst_state->pbn_div);
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  940  	}
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  941  }
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  942  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement
@ 2023-08-04  9:19     ` kernel test robot
  0 siblings, 0 replies; 38+ messages in thread
From: kernel test robot @ 2023-08-04  9:19 UTC (permalink / raw)
  To: Wayne Lin, dri-devel, amd-gfx
  Cc: jani.nikula, jerry.zuo, Wayne Lin, oe-kbuild-all

Hi Wayne,

kernel test robot noticed the following build warnings:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on drm-intel/for-linux-next-fixes drm/drm-next linus/master v6.5-rc4 next-20230804]
[cannot apply to drm-intel/for-linux-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Wayne-Lin/drm-mst-delete-unnecessary-case-in-drm_dp_add_payload_part2/20230804-142405
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:    https://lore.kernel.org/r/20230804062029.5686-3-Wayne.Lin%40amd.com
patch subject: [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement
config: microblaze-randconfig-r021-20230731 (https://download.01.org/0day-ci/archive/20230804/202308041635.WkgWWX5r-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230804/202308041635.WkgWWX5r-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308041635.WkgWWX5r-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/nouveau/dispnv50/disp.c: In function 'nv50_msto_prepare':
>> drivers/gpu/drm/nouveau/dispnv50/disp.c:919:53: warning: variable 'old_payload' set but not used [-Wunused-but-set-variable]
     919 |         struct drm_dp_mst_atomic_payload *payload, *old_payload;
         |                                                     ^~~~~~~~~~~


vim +/old_payload +919 drivers/gpu/drm/nouveau/dispnv50/disp.c

f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  908  
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  909  static void
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  910  nv50_msto_prepare(struct drm_atomic_state *state,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  911  		  struct drm_dp_mst_topology_state *mst_state,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  912  		  struct drm_dp_mst_topology_mgr *mgr,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  913  		  struct nv50_msto *msto)
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  914  {
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  915  	struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  916  	struct nv50_mstc *mstc = msto->mstc;
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  917  	struct nv50_mstm *mstm = mstc->mstm;
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  918  	struct drm_dp_mst_topology_state *old_mst_state;
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13 @919  	struct drm_dp_mst_atomic_payload *payload, *old_payload;
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  920  
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  921  	NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  922  
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  923  	old_mst_state = drm_atomic_get_old_mst_topology_state(state, mgr);
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  924  
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  925  	payload = drm_atomic_get_mst_payload_state(mst_state, mstc->port);
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  926  	old_payload = drm_atomic_get_mst_payload_state(old_mst_state, mstc->port);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  927  
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  928  	// TODO: Figure out if we want to do a better job of handling VCPI allocation failures here?
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  929  	if (msto->disabled) {
c9e8c7f37133c0 drivers/gpu/drm/nouveau/dispnv50/disp.c Wayne Lin  2023-08-04  930  		drm_dp_remove_payload_part1(mgr, mst_state, payload);
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  931  
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  932  		nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index, 0, 0, 0, 0);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  933  	} else {
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  934  		if (msto->enabled)
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  935  			drm_dp_add_payload_part1(mgr, mst_state, payload);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  936  
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  937  		nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index,
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  938  				      payload->vc_start_slot, payload->time_slots,
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  939  				      payload->pbn, payload->time_slots * mst_state->pbn_div);
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  940  	}
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  941  }
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  942  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement
  2023-08-04  6:20   ` Wayne Lin
@ 2023-08-04 14:47     ` kernel test robot
  -1 siblings, 0 replies; 38+ messages in thread
From: kernel test robot @ 2023-08-04 14:47 UTC (permalink / raw)
  To: Wayne Lin, dri-devel, amd-gfx
  Cc: llvm, oe-kbuild-all, jani.nikula, jerry.zuo, Wayne Lin

Hi Wayne,

kernel test robot noticed the following build warnings:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on drm-intel/for-linux-next-fixes drm/drm-next linus/master v6.5-rc4 next-20230804]
[cannot apply to drm-intel/for-linux-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Wayne-Lin/drm-mst-delete-unnecessary-case-in-drm_dp_add_payload_part2/20230804-142405
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:    https://lore.kernel.org/r/20230804062029.5686-3-Wayne.Lin%40amd.com
patch subject: [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement
config: s390-randconfig-r044-20230731 (https://download.01.org/0day-ci/archive/20230804/202308042253.lM5xMnnA-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
reproduce: (https://download.01.org/0day-ci/archive/20230804/202308042253.lM5xMnnA-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308042253.lM5xMnnA-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.c:24:
   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mem.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mmu.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/object.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/os.h:8:
   In file included from include/linux/pci.h:39:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     547 |         val = __raw_readb(PCI_IOBASE + addr);
         |                           ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     560 |         val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:37:59: note: expanded from macro '__le16_to_cpu'
      37 | #define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
         |                                                           ^
   include/uapi/linux/swab.h:102:54: note: expanded from macro '__swab16'
     102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
         |                                                      ^
   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.c:24:
   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mem.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mmu.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/object.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/os.h:8:
   In file included from include/linux/pci.h:39:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     573 |         val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:35:59: note: expanded from macro '__le32_to_cpu'
      35 | #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
         |                                                           ^
   include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32'
     115 | #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
         |                                                      ^
   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.c:24:
   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mem.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mmu.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/object.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/os.h:8:
   In file included from include/linux/pci.h:39:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     584 |         __raw_writeb(value, PCI_IOBASE + addr);
         |                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     594 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     604 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:692:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     692 |         readsb(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:700:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     700 |         readsw(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:708:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     708 |         readsl(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:717:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     717 |         writesb(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:726:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     726 |         writesw(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:735:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     735 |         writesl(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
>> drivers/gpu/drm/nouveau/dispnv50/disp.c:919:46: warning: variable 'old_payload' set but not used [-Wunused-but-set-variable]
     919 |         struct drm_dp_mst_atomic_payload *payload, *old_payload;
         |                                                     ^
   13 warnings generated.


vim +/old_payload +919 drivers/gpu/drm/nouveau/dispnv50/disp.c

f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  908  
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  909  static void
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  910  nv50_msto_prepare(struct drm_atomic_state *state,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  911  		  struct drm_dp_mst_topology_state *mst_state,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  912  		  struct drm_dp_mst_topology_mgr *mgr,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  913  		  struct nv50_msto *msto)
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  914  {
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  915  	struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  916  	struct nv50_mstc *mstc = msto->mstc;
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  917  	struct nv50_mstm *mstm = mstc->mstm;
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  918  	struct drm_dp_mst_topology_state *old_mst_state;
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13 @919  	struct drm_dp_mst_atomic_payload *payload, *old_payload;
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  920  
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  921  	NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  922  
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  923  	old_mst_state = drm_atomic_get_old_mst_topology_state(state, mgr);
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  924  
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  925  	payload = drm_atomic_get_mst_payload_state(mst_state, mstc->port);
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  926  	old_payload = drm_atomic_get_mst_payload_state(old_mst_state, mstc->port);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  927  
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  928  	// TODO: Figure out if we want to do a better job of handling VCPI allocation failures here?
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  929  	if (msto->disabled) {
c9e8c7f37133c0 drivers/gpu/drm/nouveau/dispnv50/disp.c Wayne Lin  2023-08-04  930  		drm_dp_remove_payload_part1(mgr, mst_state, payload);
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  931  
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  932  		nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index, 0, 0, 0, 0);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  933  	} else {
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  934  		if (msto->enabled)
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  935  			drm_dp_add_payload_part1(mgr, mst_state, payload);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  936  
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  937  		nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index,
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  938  				      payload->vc_start_slot, payload->time_slots,
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  939  				      payload->pbn, payload->time_slots * mst_state->pbn_div);
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  940  	}
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  941  }
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  942  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement
@ 2023-08-04 14:47     ` kernel test robot
  0 siblings, 0 replies; 38+ messages in thread
From: kernel test robot @ 2023-08-04 14:47 UTC (permalink / raw)
  To: Wayne Lin, dri-devel, amd-gfx
  Cc: jani.nikula, jerry.zuo, llvm, Wayne Lin, oe-kbuild-all

Hi Wayne,

kernel test robot noticed the following build warnings:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on drm-intel/for-linux-next-fixes drm/drm-next linus/master v6.5-rc4 next-20230804]
[cannot apply to drm-intel/for-linux-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Wayne-Lin/drm-mst-delete-unnecessary-case-in-drm_dp_add_payload_part2/20230804-142405
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:    https://lore.kernel.org/r/20230804062029.5686-3-Wayne.Lin%40amd.com
patch subject: [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement
config: s390-randconfig-r044-20230731 (https://download.01.org/0day-ci/archive/20230804/202308042253.lM5xMnnA-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
reproduce: (https://download.01.org/0day-ci/archive/20230804/202308042253.lM5xMnnA-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308042253.lM5xMnnA-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.c:24:
   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mem.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mmu.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/object.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/os.h:8:
   In file included from include/linux/pci.h:39:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     547 |         val = __raw_readb(PCI_IOBASE + addr);
         |                           ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     560 |         val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:37:59: note: expanded from macro '__le16_to_cpu'
      37 | #define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
         |                                                           ^
   include/uapi/linux/swab.h:102:54: note: expanded from macro '__swab16'
     102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
         |                                                      ^
   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.c:24:
   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mem.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mmu.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/object.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/os.h:8:
   In file included from include/linux/pci.h:39:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     573 |         val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:35:59: note: expanded from macro '__le32_to_cpu'
      35 | #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
         |                                                           ^
   include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32'
     115 | #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
         |                                                      ^
   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.c:24:
   In file included from drivers/gpu/drm/nouveau/dispnv50/disp.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mem.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/mmu.h:3:
   In file included from drivers/gpu/drm/nouveau/include/nvif/object.h:4:
   In file included from drivers/gpu/drm/nouveau/include/nvif/os.h:8:
   In file included from include/linux/pci.h:39:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     584 |         __raw_writeb(value, PCI_IOBASE + addr);
         |                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     594 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     604 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:692:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     692 |         readsb(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:700:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     700 |         readsw(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:708:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     708 |         readsl(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:717:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     717 |         writesb(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:726:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     726 |         writesw(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:735:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     735 |         writesl(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
>> drivers/gpu/drm/nouveau/dispnv50/disp.c:919:46: warning: variable 'old_payload' set but not used [-Wunused-but-set-variable]
     919 |         struct drm_dp_mst_atomic_payload *payload, *old_payload;
         |                                                     ^
   13 warnings generated.


vim +/old_payload +919 drivers/gpu/drm/nouveau/dispnv50/disp.c

f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  908  
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  909  static void
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  910  nv50_msto_prepare(struct drm_atomic_state *state,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  911  		  struct drm_dp_mst_topology_state *mst_state,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  912  		  struct drm_dp_mst_topology_mgr *mgr,
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  913  		  struct nv50_msto *msto)
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  914  {
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  915  	struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  916  	struct nv50_mstc *mstc = msto->mstc;
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  917  	struct nv50_mstm *mstm = mstc->mstm;
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  918  	struct drm_dp_mst_topology_state *old_mst_state;
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13 @919  	struct drm_dp_mst_atomic_payload *payload, *old_payload;
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  920  
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  921  	NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  922  
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  923  	old_mst_state = drm_atomic_get_old_mst_topology_state(state, mgr);
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  924  
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  925  	payload = drm_atomic_get_mst_payload_state(mst_state, mstc->port);
8fb3e25c3dd1a2 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2023-06-13  926  	old_payload = drm_atomic_get_mst_payload_state(old_mst_state, mstc->port);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  927  
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  928  	// TODO: Figure out if we want to do a better job of handling VCPI allocation failures here?
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  929  	if (msto->disabled) {
c9e8c7f37133c0 drivers/gpu/drm/nouveau/dispnv50/disp.c Wayne Lin  2023-08-04  930  		drm_dp_remove_payload_part1(mgr, mst_state, payload);
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  931  
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  932  		nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index, 0, 0, 0, 0);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  933  	} else {
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  934  		if (msto->enabled)
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  935  			drm_dp_add_payload_part1(mgr, mst_state, payload);
4d07b0bc403403 drivers/gpu/drm/nouveau/dispnv50/disp.c Lyude Paul 2022-08-17  936  
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  937  		nvif_outp_dp_mst_vcpi(&mstm->outp->outp, msto->head->base.index,
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  938  				      payload->vc_start_slot, payload->time_slots,
8c7d980da9ba3e drivers/gpu/drm/nouveau/dispnv50/disp.c Ben Skeggs 2022-06-01  939  				      payload->pbn, payload->time_slots * mst_state->pbn_div);
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  940  	}
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  941  }
f479c0ba4a170a drivers/gpu/drm/nouveau/nv50_display.c  Ben Skeggs 2016-11-04  942  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-08-04  6:20   ` Wayne Lin
@ 2023-08-04 15:31     ` Imre Deak
  -1 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-08-04 15:31 UTC (permalink / raw)
  To: Wayne Lin; +Cc: jani.nikula, amd-gfx, jerry.zuo, dri-devel

On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> [...]
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index e04f87ff755a..4270178f95f6 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -3382,8 +3382,7 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part1);
>   * drm_dp_remove_payload_part2() - Remove an MST payload locally
>   * @mgr: Manager to use.
>   * @mst_state: The MST atomic state
> - * @old_payload: The payload with its old state
> - * @new_payload: The payload with its latest state
> + * @payload: The payload with its latest state
>   *
>   * Updates the starting time slots of all other payloads which would have been shifted towards
>   * the start of the payload ID table as a result of removing a payload. Driver should call this
> @@ -3392,25 +3391,36 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part1);
>   */
>  void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
>  				 struct drm_dp_mst_topology_state *mst_state,
> -				 const struct drm_dp_mst_atomic_payload *old_payload,
> -				 struct drm_dp_mst_atomic_payload *new_payload)
> +				 struct drm_dp_mst_atomic_payload *payload)
>  {
>  	struct drm_dp_mst_atomic_payload *pos;
> +	u8 time_slots_to_remove;
> +	u8 next_payload_vc_start = mgr->next_start_slot;
> +
> +	/* Find the current allocated time slot number of the payload */
> +	list_for_each_entry(pos, &mst_state->payloads, next) {
> +		if (pos != payload &&
> +		    pos->vc_start_slot > payload->vc_start_slot &&
> +		    pos->vc_start_slot < next_payload_vc_start)
> +			next_payload_vc_start = pos->vc_start_slot;
> +	}
> +
> +	time_slots_to_remove = next_payload_vc_start - payload->vc_start_slot;

Imo, the intuitive way would be to pass the old payload state to this
function - which already contains the required time_slots param - and
refactor things instead moving vc_start_slot from the payload state to
mgr suggested by Ville earlier.

--Imre

>  	/* Remove local payload allocation */
>  	list_for_each_entry(pos, &mst_state->payloads, next) {
> -		if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)
> -			pos->vc_start_slot -= old_payload->time_slots;
> +		if (pos != payload && pos->vc_start_slot > payload->vc_start_slot)
> +			pos->vc_start_slot -= time_slots_to_remove;
>  	}
> -	new_payload->vc_start_slot = -1;
> +	payload->vc_start_slot = -1;
>  
>  	mgr->payload_count--;
> -	mgr->next_start_slot -= old_payload->time_slots;
> +	mgr->next_start_slot -= time_slots_to_remove;
>  
> -	if (new_payload->delete)
> -		drm_dp_mst_put_port_malloc(new_payload->port);
> +	if (payload->delete)
> +		drm_dp_mst_put_port_malloc(payload->port);
>  
> -	new_payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> +	payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
>  }

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-08-04 15:31     ` Imre Deak
  0 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-08-04 15:31 UTC (permalink / raw)
  To: Wayne Lin
  Cc: jani.nikula, amd-gfx, jerry.zuo, dri-devel, harry.wentland,
	ville.syrjala

On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> [...]
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index e04f87ff755a..4270178f95f6 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -3382,8 +3382,7 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part1);
>   * drm_dp_remove_payload_part2() - Remove an MST payload locally
>   * @mgr: Manager to use.
>   * @mst_state: The MST atomic state
> - * @old_payload: The payload with its old state
> - * @new_payload: The payload with its latest state
> + * @payload: The payload with its latest state
>   *
>   * Updates the starting time slots of all other payloads which would have been shifted towards
>   * the start of the payload ID table as a result of removing a payload. Driver should call this
> @@ -3392,25 +3391,36 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part1);
>   */
>  void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
>  				 struct drm_dp_mst_topology_state *mst_state,
> -				 const struct drm_dp_mst_atomic_payload *old_payload,
> -				 struct drm_dp_mst_atomic_payload *new_payload)
> +				 struct drm_dp_mst_atomic_payload *payload)
>  {
>  	struct drm_dp_mst_atomic_payload *pos;
> +	u8 time_slots_to_remove;
> +	u8 next_payload_vc_start = mgr->next_start_slot;
> +
> +	/* Find the current allocated time slot number of the payload */
> +	list_for_each_entry(pos, &mst_state->payloads, next) {
> +		if (pos != payload &&
> +		    pos->vc_start_slot > payload->vc_start_slot &&
> +		    pos->vc_start_slot < next_payload_vc_start)
> +			next_payload_vc_start = pos->vc_start_slot;
> +	}
> +
> +	time_slots_to_remove = next_payload_vc_start - payload->vc_start_slot;

Imo, the intuitive way would be to pass the old payload state to this
function - which already contains the required time_slots param - and
refactor things instead moving vc_start_slot from the payload state to
mgr suggested by Ville earlier.

--Imre

>  	/* Remove local payload allocation */
>  	list_for_each_entry(pos, &mst_state->payloads, next) {
> -		if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)
> -			pos->vc_start_slot -= old_payload->time_slots;
> +		if (pos != payload && pos->vc_start_slot > payload->vc_start_slot)
> +			pos->vc_start_slot -= time_slots_to_remove;
>  	}
> -	new_payload->vc_start_slot = -1;
> +	payload->vc_start_slot = -1;
>  
>  	mgr->payload_count--;
> -	mgr->next_start_slot -= old_payload->time_slots;
> +	mgr->next_start_slot -= time_slots_to_remove;
>  
> -	if (new_payload->delete)
> -		drm_dp_mst_put_port_malloc(new_payload->port);
> +	if (payload->delete)
> +		drm_dp_mst_put_port_malloc(payload->port);
>  
> -	new_payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> +	payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
>  }

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-08-04 15:31     ` Imre Deak
@ 2023-08-07  2:43       ` Lin, Wayne
  -1 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-08-07  2:43 UTC (permalink / raw)
  To: imre.deak; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

[AMD Official Use Only - General]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Friday, August 4, 2023 11:32 PM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > [...]
> > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > index e04f87ff755a..4270178f95f6 100644
> > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > @@ -3382,8 +3382,7 @@
> EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> >   * drm_dp_remove_payload_part2() - Remove an MST payload locally
> >   * @mgr: Manager to use.
> >   * @mst_state: The MST atomic state
> > - * @old_payload: The payload with its old state
> > - * @new_payload: The payload with its latest state
> > + * @payload: The payload with its latest state
> >   *
> >   * Updates the starting time slots of all other payloads which would have
> been shifted towards
> >   * the start of the payload ID table as a result of removing a
> > payload. Driver should call this @@ -3392,25 +3391,36 @@
> EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> >   */
> >  void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr
> *mgr,
> >                              struct drm_dp_mst_topology_state
> *mst_state,
> > -                            const struct drm_dp_mst_atomic_payload
> *old_payload,
> > -                            struct drm_dp_mst_atomic_payload
> *new_payload)
> > +                            struct drm_dp_mst_atomic_payload
> *payload)
> >  {
> >     struct drm_dp_mst_atomic_payload *pos;
> > +   u8 time_slots_to_remove;
> > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > +
> > +   /* Find the current allocated time slot number of the payload */
> > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > +           if (pos != payload &&
> > +               pos->vc_start_slot > payload->vc_start_slot &&
> > +               pos->vc_start_slot < next_payload_vc_start)
> > +                   next_payload_vc_start = pos->vc_start_slot;
> > +   }
> > +
> > +   time_slots_to_remove = next_payload_vc_start -
> > +payload->vc_start_slot;
>
> Imo, the intuitive way would be to pass the old payload state to this function -
> which already contains the required time_slots param - and refactor things
> instead moving vc_start_slot from the payload state to mgr suggested by Ville
> earlier.
>
> --Imre

Hi Imre,
Thanks for your feedback!
I understand it's functionally correct. But IMHO, it's still a bit conceptually
different between the time slot in old state and the time slot in current payload
table. My thought is the time slot at the moment when we are removing the
payload would be a better choice. And with this, we can also simplify some
codes. Especially remove workaround in amd driver. In fact, DRM mst code
maintains the payload table and all the time slot info is in it already. We don't
really have to pass a new parameter.

>
> >     /* Remove local payload allocation */
> >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> >vc_start_slot)
> > -                   pos->vc_start_slot -= old_payload->time_slots;
> > +           if (pos != payload && pos->vc_start_slot > payload-
> >vc_start_slot)
> > +                   pos->vc_start_slot -= time_slots_to_remove;
> >     }
> > -   new_payload->vc_start_slot = -1;
> > +   payload->vc_start_slot = -1;
> >
> >     mgr->payload_count--;
> > -   mgr->next_start_slot -= old_payload->time_slots;
> > +   mgr->next_start_slot -= time_slots_to_remove;
> >
> > -   if (new_payload->delete)
> > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > +   if (payload->delete)
> > +           drm_dp_mst_put_port_malloc(payload->port);
> >
> > -   new_payload->payload_allocation_status =
> DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > +   payload->payload_allocation_status =
> > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> >  }

--
Regards,
Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-08-07  2:43       ` Lin, Wayne
  0 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-08-07  2:43 UTC (permalink / raw)
  To: imre.deak
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

[AMD Official Use Only - General]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Friday, August 4, 2023 11:32 PM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > [...]
> > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > index e04f87ff755a..4270178f95f6 100644
> > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > @@ -3382,8 +3382,7 @@
> EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> >   * drm_dp_remove_payload_part2() - Remove an MST payload locally
> >   * @mgr: Manager to use.
> >   * @mst_state: The MST atomic state
> > - * @old_payload: The payload with its old state
> > - * @new_payload: The payload with its latest state
> > + * @payload: The payload with its latest state
> >   *
> >   * Updates the starting time slots of all other payloads which would have
> been shifted towards
> >   * the start of the payload ID table as a result of removing a
> > payload. Driver should call this @@ -3392,25 +3391,36 @@
> EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> >   */
> >  void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr
> *mgr,
> >                              struct drm_dp_mst_topology_state
> *mst_state,
> > -                            const struct drm_dp_mst_atomic_payload
> *old_payload,
> > -                            struct drm_dp_mst_atomic_payload
> *new_payload)
> > +                            struct drm_dp_mst_atomic_payload
> *payload)
> >  {
> >     struct drm_dp_mst_atomic_payload *pos;
> > +   u8 time_slots_to_remove;
> > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > +
> > +   /* Find the current allocated time slot number of the payload */
> > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > +           if (pos != payload &&
> > +               pos->vc_start_slot > payload->vc_start_slot &&
> > +               pos->vc_start_slot < next_payload_vc_start)
> > +                   next_payload_vc_start = pos->vc_start_slot;
> > +   }
> > +
> > +   time_slots_to_remove = next_payload_vc_start -
> > +payload->vc_start_slot;
>
> Imo, the intuitive way would be to pass the old payload state to this function -
> which already contains the required time_slots param - and refactor things
> instead moving vc_start_slot from the payload state to mgr suggested by Ville
> earlier.
>
> --Imre

Hi Imre,
Thanks for your feedback!
I understand it's functionally correct. But IMHO, it's still a bit conceptually
different between the time slot in old state and the time slot in current payload
table. My thought is the time slot at the moment when we are removing the
payload would be a better choice. And with this, we can also simplify some
codes. Especially remove workaround in amd driver. In fact, DRM mst code
maintains the payload table and all the time slot info is in it already. We don't
really have to pass a new parameter.

>
> >     /* Remove local payload allocation */
> >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> >vc_start_slot)
> > -                   pos->vc_start_slot -= old_payload->time_slots;
> > +           if (pos != payload && pos->vc_start_slot > payload-
> >vc_start_slot)
> > +                   pos->vc_start_slot -= time_slots_to_remove;
> >     }
> > -   new_payload->vc_start_slot = -1;
> > +   payload->vc_start_slot = -1;
> >
> >     mgr->payload_count--;
> > -   mgr->next_start_slot -= old_payload->time_slots;
> > +   mgr->next_start_slot -= time_slots_to_remove;
> >
> > -   if (new_payload->delete)
> > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > +   if (payload->delete)
> > +           drm_dp_mst_put_port_malloc(payload->port);
> >
> > -   new_payload->payload_allocation_status =
> DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > +   payload->payload_allocation_status =
> > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> >  }

--
Regards,
Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-08-07  2:43       ` Lin, Wayne
@ 2023-08-07 15:59         ` Imre Deak
  -1 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-08-07 15:59 UTC (permalink / raw)
  To: Lin, Wayne; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> [AMD Official Use Only - General]
> 
> > -----Original Message-----
> > From: Imre Deak <imre.deak@intel.com>
> > Sent: Friday, August 4, 2023 11:32 PM
> > To: Lin, Wayne <Wayne.Lin@amd.com>
> > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > <Jerry.Zuo@amd.com>
> > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > drm_dp_remove_payload_part2()
> >
> > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > [...]
> > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > index e04f87ff755a..4270178f95f6 100644
> > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > @@ -3382,8 +3382,7 @@
> > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > >   * drm_dp_remove_payload_part2() - Remove an MST payload locally
> > >   * @mgr: Manager to use.
> > >   * @mst_state: The MST atomic state
> > > - * @old_payload: The payload with its old state
> > > - * @new_payload: The payload with its latest state
> > > + * @payload: The payload with its latest state
> > >   *
> > >   * Updates the starting time slots of all other payloads which would have
> > been shifted towards
> > >   * the start of the payload ID table as a result of removing a
> > > payload. Driver should call this @@ -3392,25 +3391,36 @@
> > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > >   */
> > >  void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr
> > *mgr,
> > >                              struct drm_dp_mst_topology_state
> > *mst_state,
> > > -                            const struct drm_dp_mst_atomic_payload
> > *old_payload,
> > > -                            struct drm_dp_mst_atomic_payload
> > *new_payload)
> > > +                            struct drm_dp_mst_atomic_payload
> > *payload)
> > >  {
> > >     struct drm_dp_mst_atomic_payload *pos;
> > > +   u8 time_slots_to_remove;
> > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > +
> > > +   /* Find the current allocated time slot number of the payload */
> > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > +           if (pos != payload &&
> > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > +               pos->vc_start_slot < next_payload_vc_start)
> > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > +   }
> > > +
> > > +   time_slots_to_remove = next_payload_vc_start -
> > > +payload->vc_start_slot;
> >
> > Imo, the intuitive way would be to pass the old payload state to this function -
> > which already contains the required time_slots param - and refactor things
> > instead moving vc_start_slot from the payload state to mgr suggested by Ville
> > earlier.
> >
> > --Imre
> 
> Hi Imre,
> Thanks for your feedback!
>
> I understand it's functionally correct. But IMHO, it's still a bit
> conceptually different between the time slot in old state and the time
> slot in current payload table. My thought is the time slot at the
> moment when we are removing the payload would be a better choice.

Yes, they are different. The old state contains the time slot the
payload was added with in a preceding commit and so the time slot value
which should be used when removing the same payload in the current
commit.

The new state contains a time slot value with which the payload will be
added in the current commit and can be different than the one in the old
state if the current commit has changed the payload size (meaning that
the same atomic commit will first remove the payload using the time slot
value in the old state and afterwards will add back the same payload
using the time slot value in the new state).

> And with this, we can also simplify some codes. Especially remove
> workaround in amd driver. In fact, DRM mst code maintains the payload
> table and all the time slot info is in it already. We don't really
> have to pass a new parameter.

I agree that drm_dp_remove_payload() could be simplified, but this
should be done so that the drivers can pass the old payload state to it
(without having to pass the new state). This would be possible if
vc_start_slot was not tracked in the payload state (which is really not
an atomic state that can be precomputed as all other atomic state),
rather it would be tracked in struct drm_dp_mst_topology_mgr.

It looks like AMD has to reconstruct the old state in
dm_helpers_construct_old_payload(). Could you explain why it couldn't
instead just pass old_payload acquired by

old_mst_state = drm_atomic_get_old_mst_topology_state();
old_payload = drm_atomic_get_mst_payload_state(old_mst_state);

?

> > >     /* Remove local payload allocation */
> > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > >vc_start_slot)
> > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > +           if (pos != payload && pos->vc_start_slot > payload-
> > >vc_start_slot)
> > > +                   pos->vc_start_slot -= time_slots_to_remove;
> > >     }
> > > -   new_payload->vc_start_slot = -1;
> > > +   payload->vc_start_slot = -1;
> > >
> > >     mgr->payload_count--;
> > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > +   mgr->next_start_slot -= time_slots_to_remove;
> > >
> > > -   if (new_payload->delete)
> > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > +   if (payload->delete)
> > > +           drm_dp_mst_put_port_malloc(payload->port);
> > >
> > > -   new_payload->payload_allocation_status =
> > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > +   payload->payload_allocation_status =
> > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > >  }
> 
> --
> Regards,
> Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-08-07 15:59         ` Imre Deak
  0 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-08-07 15:59 UTC (permalink / raw)
  To: Lin, Wayne
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> [AMD Official Use Only - General]
> 
> > -----Original Message-----
> > From: Imre Deak <imre.deak@intel.com>
> > Sent: Friday, August 4, 2023 11:32 PM
> > To: Lin, Wayne <Wayne.Lin@amd.com>
> > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > <Jerry.Zuo@amd.com>
> > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > drm_dp_remove_payload_part2()
> >
> > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > [...]
> > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > index e04f87ff755a..4270178f95f6 100644
> > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > @@ -3382,8 +3382,7 @@
> > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > >   * drm_dp_remove_payload_part2() - Remove an MST payload locally
> > >   * @mgr: Manager to use.
> > >   * @mst_state: The MST atomic state
> > > - * @old_payload: The payload with its old state
> > > - * @new_payload: The payload with its latest state
> > > + * @payload: The payload with its latest state
> > >   *
> > >   * Updates the starting time slots of all other payloads which would have
> > been shifted towards
> > >   * the start of the payload ID table as a result of removing a
> > > payload. Driver should call this @@ -3392,25 +3391,36 @@
> > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > >   */
> > >  void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr
> > *mgr,
> > >                              struct drm_dp_mst_topology_state
> > *mst_state,
> > > -                            const struct drm_dp_mst_atomic_payload
> > *old_payload,
> > > -                            struct drm_dp_mst_atomic_payload
> > *new_payload)
> > > +                            struct drm_dp_mst_atomic_payload
> > *payload)
> > >  {
> > >     struct drm_dp_mst_atomic_payload *pos;
> > > +   u8 time_slots_to_remove;
> > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > +
> > > +   /* Find the current allocated time slot number of the payload */
> > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > +           if (pos != payload &&
> > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > +               pos->vc_start_slot < next_payload_vc_start)
> > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > +   }
> > > +
> > > +   time_slots_to_remove = next_payload_vc_start -
> > > +payload->vc_start_slot;
> >
> > Imo, the intuitive way would be to pass the old payload state to this function -
> > which already contains the required time_slots param - and refactor things
> > instead moving vc_start_slot from the payload state to mgr suggested by Ville
> > earlier.
> >
> > --Imre
> 
> Hi Imre,
> Thanks for your feedback!
>
> I understand it's functionally correct. But IMHO, it's still a bit
> conceptually different between the time slot in old state and the time
> slot in current payload table. My thought is the time slot at the
> moment when we are removing the payload would be a better choice.

Yes, they are different. The old state contains the time slot the
payload was added with in a preceding commit and so the time slot value
which should be used when removing the same payload in the current
commit.

The new state contains a time slot value with which the payload will be
added in the current commit and can be different than the one in the old
state if the current commit has changed the payload size (meaning that
the same atomic commit will first remove the payload using the time slot
value in the old state and afterwards will add back the same payload
using the time slot value in the new state).

> And with this, we can also simplify some codes. Especially remove
> workaround in amd driver. In fact, DRM mst code maintains the payload
> table and all the time slot info is in it already. We don't really
> have to pass a new parameter.

I agree that drm_dp_remove_payload() could be simplified, but this
should be done so that the drivers can pass the old payload state to it
(without having to pass the new state). This would be possible if
vc_start_slot was not tracked in the payload state (which is really not
an atomic state that can be precomputed as all other atomic state),
rather it would be tracked in struct drm_dp_mst_topology_mgr.

It looks like AMD has to reconstruct the old state in
dm_helpers_construct_old_payload(). Could you explain why it couldn't
instead just pass old_payload acquired by

old_mst_state = drm_atomic_get_old_mst_topology_state();
old_payload = drm_atomic_get_mst_payload_state(old_mst_state);

?

> > >     /* Remove local payload allocation */
> > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > >vc_start_slot)
> > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > +           if (pos != payload && pos->vc_start_slot > payload-
> > >vc_start_slot)
> > > +                   pos->vc_start_slot -= time_slots_to_remove;
> > >     }
> > > -   new_payload->vc_start_slot = -1;
> > > +   payload->vc_start_slot = -1;
> > >
> > >     mgr->payload_count--;
> > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > +   mgr->next_start_slot -= time_slots_to_remove;
> > >
> > > -   if (new_payload->delete)
> > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > +   if (payload->delete)
> > > +           drm_dp_mst_put_port_malloc(payload->port);
> > >
> > > -   new_payload->payload_allocation_status =
> > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > +   payload->payload_allocation_status =
> > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > >  }
> 
> --
> Regards,
> Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-08-07 15:59         ` Imre Deak
@ 2023-08-08  3:47           ` Lin, Wayne
  -1 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-08-08  3:47 UTC (permalink / raw)
  To: imre.deak; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

[AMD Official Use Only - General]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Tuesday, August 8, 2023 12:00 AM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > [AMD Official Use Only - General]
> >
> > > -----Original Message-----
> > > From: Imre Deak <imre.deak@intel.com>
> > > Sent: Friday, August 4, 2023 11:32 PM
> > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > lyude@redhat.com; jani.nikula@intel.com;
> > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > drm_dp_remove_payload_part2()
> > >
> > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > [...]
> > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > index e04f87ff755a..4270178f95f6 100644
> > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > @@ -3382,8 +3382,7 @@
> > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > >   * drm_dp_remove_payload_part2() - Remove an MST payload locally
> > > >   * @mgr: Manager to use.
> > > >   * @mst_state: The MST atomic state
> > > > - * @old_payload: The payload with its old state
> > > > - * @new_payload: The payload with its latest state
> > > > + * @payload: The payload with its latest state
> > > >   *
> > > >   * Updates the starting time slots of all other payloads which
> > > > would have
> > > been shifted towards
> > > >   * the start of the payload ID table as a result of removing a
> > > > payload. Driver should call this @@ -3392,25 +3391,36 @@
> > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > >   */
> > > >  void drm_dp_remove_payload_part2(struct
> drm_dp_mst_topology_mgr
> > > *mgr,
> > > >                              struct drm_dp_mst_topology_state
> > > *mst_state,
> > > > -                            const struct drm_dp_mst_atomic_payload
> > > *old_payload,
> > > > -                            struct drm_dp_mst_atomic_payload
> > > *new_payload)
> > > > +                            struct drm_dp_mst_atomic_payload
> > > *payload)
> > > >  {
> > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > +   u8 time_slots_to_remove;
> > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > +
> > > > +   /* Find the current allocated time slot number of the payload */
> > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > +           if (pos != payload &&
> > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > +   }
> > > > +
> > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > +payload->vc_start_slot;
> > >
> > > Imo, the intuitive way would be to pass the old payload state to
> > > this function - which already contains the required time_slots param
> > > - and refactor things instead moving vc_start_slot from the payload
> > > state to mgr suggested by Ville earlier.
> > >
> > > --Imre
> >
> > Hi Imre,
> > Thanks for your feedback!
> >
> > I understand it's functionally correct. But IMHO, it's still a bit
> > conceptually different between the time slot in old state and the time
> > slot in current payload table. My thought is the time slot at the
> > moment when we are removing the payload would be a better choice.
>
> Yes, they are different. The old state contains the time slot the payload was
> added with in a preceding commit and so the time slot value which should be
> used when removing the same payload in the current commit.
>
> The new state contains a time slot value with which the payload will be added
> in the current commit and can be different than the one in the old state if the
> current commit has changed the payload size (meaning that the same atomic
> commit will first remove the payload using the time slot value in the old state
> and afterwards will add back the same payload using the time slot value in the
> new state).
>
Appreciate your time, Imre!

Yes I understand, so I'm not using the number of the time slot in the new state.
I'm referring to the start slot instead which is updated during every allocation
and removement at current commit.

Like what you said, current commit manipulation could be a mix of allocations
and removements for the payload. My thought is, conceptually, looking up the
latest number of time slot is a better choice rather than the one in old state.
It's relatively intuitive to me since we are removing payload from current
payload table and which changes since last preceding commit till the moment
we're deleting the payload. Although it's unreasonable that these values are
different.

> > And with this, we can also simplify some codes. Especially remove
> > workaround in amd driver. In fact, DRM mst code maintains the payload
> > table and all the time slot info is in it already. We don't really
> > have to pass a new parameter.
>
> I agree that drm_dp_remove_payload() could be simplified, but this should be
> done so that the drivers can pass the old payload state to it (without having to
> pass the new state). This would be possible if vc_start_slot was not tracked in
> the payload state (which is really not an atomic state that can be precomputed
> as all other atomic state), rather it would be tracked in struct
> drm_dp_mst_topology_mgr.
>

So the reason I chose to pass the new state is like what I mentioned above. I
would prefer to carry the latest updated payload table instead which is in the new
state. And I agree with the explanation for the vc_start_slot and that's also my
thought at the beginning. It could be a refactor later, but no matter the start slot
is put into payload state or the topology manager I would prefer to refer to the
latest payload table rather than the number of time slot in the old state.

> It looks like AMD has to reconstruct the old state in
> dm_helpers_construct_old_payload(). Could you explain why it couldn't
> instead just pass old_payload acquired by
>
> old_mst_state = drm_atomic_get_old_mst_topology_state();
> old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
>
> ?

AMD doesn't pass the drm old state to the stage while HW is deleting the payload.
The reason is that HW payload table is known during HW programming procedure,
so the payload removement is based on the table at the moment. AMD expected
the current number of time slot is also already maintained in drm layer.

Again, thanks for your feedback Imre!

>
> > > >     /* Remove local payload allocation */
> > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > >vc_start_slot)
> > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > +           if (pos != payload && pos->vc_start_slot > payload-
> > > >vc_start_slot)
> > > > +                   pos->vc_start_slot -= time_slots_to_remove;
> > > >     }
> > > > -   new_payload->vc_start_slot = -1;
> > > > +   payload->vc_start_slot = -1;
> > > >
> > > >     mgr->payload_count--;
> > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > >
> > > > -   if (new_payload->delete)
> > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > +   if (payload->delete)
> > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > >
> > > > -   new_payload->payload_allocation_status =
> > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > +   payload->payload_allocation_status =
> > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > >  }
> >
> > --
> > Regards,
> > Wayne

--
Regards,
Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-08-08  3:47           ` Lin, Wayne
  0 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-08-08  3:47 UTC (permalink / raw)
  To: imre.deak
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

[AMD Official Use Only - General]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Tuesday, August 8, 2023 12:00 AM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > [AMD Official Use Only - General]
> >
> > > -----Original Message-----
> > > From: Imre Deak <imre.deak@intel.com>
> > > Sent: Friday, August 4, 2023 11:32 PM
> > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > lyude@redhat.com; jani.nikula@intel.com;
> > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > drm_dp_remove_payload_part2()
> > >
> > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > [...]
> > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > index e04f87ff755a..4270178f95f6 100644
> > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > @@ -3382,8 +3382,7 @@
> > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > >   * drm_dp_remove_payload_part2() - Remove an MST payload locally
> > > >   * @mgr: Manager to use.
> > > >   * @mst_state: The MST atomic state
> > > > - * @old_payload: The payload with its old state
> > > > - * @new_payload: The payload with its latest state
> > > > + * @payload: The payload with its latest state
> > > >   *
> > > >   * Updates the starting time slots of all other payloads which
> > > > would have
> > > been shifted towards
> > > >   * the start of the payload ID table as a result of removing a
> > > > payload. Driver should call this @@ -3392,25 +3391,36 @@
> > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > >   */
> > > >  void drm_dp_remove_payload_part2(struct
> drm_dp_mst_topology_mgr
> > > *mgr,
> > > >                              struct drm_dp_mst_topology_state
> > > *mst_state,
> > > > -                            const struct drm_dp_mst_atomic_payload
> > > *old_payload,
> > > > -                            struct drm_dp_mst_atomic_payload
> > > *new_payload)
> > > > +                            struct drm_dp_mst_atomic_payload
> > > *payload)
> > > >  {
> > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > +   u8 time_slots_to_remove;
> > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > +
> > > > +   /* Find the current allocated time slot number of the payload */
> > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > +           if (pos != payload &&
> > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > +   }
> > > > +
> > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > +payload->vc_start_slot;
> > >
> > > Imo, the intuitive way would be to pass the old payload state to
> > > this function - which already contains the required time_slots param
> > > - and refactor things instead moving vc_start_slot from the payload
> > > state to mgr suggested by Ville earlier.
> > >
> > > --Imre
> >
> > Hi Imre,
> > Thanks for your feedback!
> >
> > I understand it's functionally correct. But IMHO, it's still a bit
> > conceptually different between the time slot in old state and the time
> > slot in current payload table. My thought is the time slot at the
> > moment when we are removing the payload would be a better choice.
>
> Yes, they are different. The old state contains the time slot the payload was
> added with in a preceding commit and so the time slot value which should be
> used when removing the same payload in the current commit.
>
> The new state contains a time slot value with which the payload will be added
> in the current commit and can be different than the one in the old state if the
> current commit has changed the payload size (meaning that the same atomic
> commit will first remove the payload using the time slot value in the old state
> and afterwards will add back the same payload using the time slot value in the
> new state).
>
Appreciate your time, Imre!

Yes I understand, so I'm not using the number of the time slot in the new state.
I'm referring to the start slot instead which is updated during every allocation
and removement at current commit.

Like what you said, current commit manipulation could be a mix of allocations
and removements for the payload. My thought is, conceptually, looking up the
latest number of time slot is a better choice rather than the one in old state.
It's relatively intuitive to me since we are removing payload from current
payload table and which changes since last preceding commit till the moment
we're deleting the payload. Although it's unreasonable that these values are
different.

> > And with this, we can also simplify some codes. Especially remove
> > workaround in amd driver. In fact, DRM mst code maintains the payload
> > table and all the time slot info is in it already. We don't really
> > have to pass a new parameter.
>
> I agree that drm_dp_remove_payload() could be simplified, but this should be
> done so that the drivers can pass the old payload state to it (without having to
> pass the new state). This would be possible if vc_start_slot was not tracked in
> the payload state (which is really not an atomic state that can be precomputed
> as all other atomic state), rather it would be tracked in struct
> drm_dp_mst_topology_mgr.
>

So the reason I chose to pass the new state is like what I mentioned above. I
would prefer to carry the latest updated payload table instead which is in the new
state. And I agree with the explanation for the vc_start_slot and that's also my
thought at the beginning. It could be a refactor later, but no matter the start slot
is put into payload state or the topology manager I would prefer to refer to the
latest payload table rather than the number of time slot in the old state.

> It looks like AMD has to reconstruct the old state in
> dm_helpers_construct_old_payload(). Could you explain why it couldn't
> instead just pass old_payload acquired by
>
> old_mst_state = drm_atomic_get_old_mst_topology_state();
> old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
>
> ?

AMD doesn't pass the drm old state to the stage while HW is deleting the payload.
The reason is that HW payload table is known during HW programming procedure,
so the payload removement is based on the table at the moment. AMD expected
the current number of time slot is also already maintained in drm layer.

Again, thanks for your feedback Imre!

>
> > > >     /* Remove local payload allocation */
> > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > >vc_start_slot)
> > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > +           if (pos != payload && pos->vc_start_slot > payload-
> > > >vc_start_slot)
> > > > +                   pos->vc_start_slot -= time_slots_to_remove;
> > > >     }
> > > > -   new_payload->vc_start_slot = -1;
> > > > +   payload->vc_start_slot = -1;
> > > >
> > > >     mgr->payload_count--;
> > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > >
> > > > -   if (new_payload->delete)
> > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > +   if (payload->delete)
> > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > >
> > > > -   new_payload->payload_allocation_status =
> > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > +   payload->payload_allocation_status =
> > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > >  }
> >
> > --
> > Regards,
> > Wayne

--
Regards,
Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-08-07 15:59         ` Imre Deak
@ 2023-08-17 21:38           ` Lyude Paul
  -1 siblings, 0 replies; 38+ messages in thread
From: Lyude Paul @ 2023-08-17 21:38 UTC (permalink / raw)
  To: imre.deak, Lin, Wayne; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

On Mon, 2023-08-07 at 18:59 +0300, Imre Deak wrote:
> On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > [AMD Official Use Only - General]
> > 
> > > -----Original Message-----
> > > From: Imre Deak <imre.deak@intel.com>
> > > Sent: Friday, August 4, 2023 11:32 PM
> > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > > <Jerry.Zuo@amd.com>
> > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > drm_dp_remove_payload_part2()
> > > 
> > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > [...]
> > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > index e04f87ff755a..4270178f95f6 100644
> > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > @@ -3382,8 +3382,7 @@
> > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > >   * drm_dp_remove_payload_part2() - Remove an MST payload locally
> > > >   * @mgr: Manager to use.
> > > >   * @mst_state: The MST atomic state
> > > > - * @old_payload: The payload with its old state
> > > > - * @new_payload: The payload with its latest state
> > > > + * @payload: The payload with its latest state
> > > >   *
> > > >   * Updates the starting time slots of all other payloads which would have
> > > been shifted towards
> > > >   * the start of the payload ID table as a result of removing a
> > > > payload. Driver should call this @@ -3392,25 +3391,36 @@
> > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > >   */
> > > >  void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr
> > > *mgr,
> > > >                              struct drm_dp_mst_topology_state
> > > *mst_state,
> > > > -                            const struct drm_dp_mst_atomic_payload
> > > *old_payload,
> > > > -                            struct drm_dp_mst_atomic_payload
> > > *new_payload)
> > > > +                            struct drm_dp_mst_atomic_payload
> > > *payload)
> > > >  {
> > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > +   u8 time_slots_to_remove;
> > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > +
> > > > +   /* Find the current allocated time slot number of the payload */
> > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > +           if (pos != payload &&
> > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > +   }
> > > > +
> > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > +payload->vc_start_slot;
> > > 
> > > Imo, the intuitive way would be to pass the old payload state to this function -
> > > which already contains the required time_slots param - and refactor things
> > > instead moving vc_start_slot from the payload state to mgr suggested by Ville
> > > earlier.
> > > 
> > > --Imre
> > 
> > Hi Imre,
> > Thanks for your feedback!
> > 
> > I understand it's functionally correct. But IMHO, it's still a bit
> > conceptually different between the time slot in old state and the time
> > slot in current payload table. My thought is the time slot at the
> > moment when we are removing the payload would be a better choice.
> 
> Yes, they are different. The old state contains the time slot the
> payload was added with in a preceding commit and so the time slot value
> which should be used when removing the same payload in the current
> commit.
> 
> The new state contains a time slot value with which the payload will be
> added in the current commit and can be different than the one in the old
> state if the current commit has changed the payload size (meaning that
> the same atomic commit will first remove the payload using the time slot
> value in the old state and afterwards will add back the same payload
> using the time slot value in the new state).
> 
> > And with this, we can also simplify some codes. Especially remove
> > workaround in amd driver. In fact, DRM mst code maintains the payload
> > table and all the time slot info is in it already. We don't really
> > have to pass a new parameter.
> 
> I agree that drm_dp_remove_payload() could be simplified, but this
> should be done so that the drivers can pass the old payload state to it
> (without having to pass the new state). This would be possible if
> vc_start_slot was not tracked in the payload state (which is really not
> an atomic state that can be precomputed as all other atomic state),
> rather it would be tracked in struct drm_dp_mst_topology_mgr.

JFYI too  - I think I'm fine with us moving vc_start_slot elsewhere at this
point ;)

> 
> It looks like AMD has to reconstruct the old state in
> dm_helpers_construct_old_payload(). Could you explain why it couldn't
> instead just pass old_payload acquired by
> 
> old_mst_state = drm_atomic_get_old_mst_topology_state();
> old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> 
> ?
> 
> > > >     /* Remove local payload allocation */
> > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > > vc_start_slot)
> > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > +           if (pos != payload && pos->vc_start_slot > payload-
> > > > vc_start_slot)
> > > > +                   pos->vc_start_slot -= time_slots_to_remove;
> > > >     }
> > > > -   new_payload->vc_start_slot = -1;
> > > > +   payload->vc_start_slot = -1;
> > > > 
> > > >     mgr->payload_count--;
> > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > 
> > > > -   if (new_payload->delete)
> > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > +   if (payload->delete)
> > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > > 
> > > > -   new_payload->payload_allocation_status =
> > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > +   payload->payload_allocation_status =
> > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > >  }
> > 
> > --
> > Regards,
> > Wayne
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-08-17 21:38           ` Lyude Paul
  0 siblings, 0 replies; 38+ messages in thread
From: Lyude Paul @ 2023-08-17 21:38 UTC (permalink / raw)
  To: imre.deak, Lin, Wayne
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

On Mon, 2023-08-07 at 18:59 +0300, Imre Deak wrote:
> On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > [AMD Official Use Only - General]
> > 
> > > -----Original Message-----
> > > From: Imre Deak <imre.deak@intel.com>
> > > Sent: Friday, August 4, 2023 11:32 PM
> > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > > <Jerry.Zuo@amd.com>
> > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > drm_dp_remove_payload_part2()
> > > 
> > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > [...]
> > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > index e04f87ff755a..4270178f95f6 100644
> > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > @@ -3382,8 +3382,7 @@
> > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > >   * drm_dp_remove_payload_part2() - Remove an MST payload locally
> > > >   * @mgr: Manager to use.
> > > >   * @mst_state: The MST atomic state
> > > > - * @old_payload: The payload with its old state
> > > > - * @new_payload: The payload with its latest state
> > > > + * @payload: The payload with its latest state
> > > >   *
> > > >   * Updates the starting time slots of all other payloads which would have
> > > been shifted towards
> > > >   * the start of the payload ID table as a result of removing a
> > > > payload. Driver should call this @@ -3392,25 +3391,36 @@
> > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > >   */
> > > >  void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr
> > > *mgr,
> > > >                              struct drm_dp_mst_topology_state
> > > *mst_state,
> > > > -                            const struct drm_dp_mst_atomic_payload
> > > *old_payload,
> > > > -                            struct drm_dp_mst_atomic_payload
> > > *new_payload)
> > > > +                            struct drm_dp_mst_atomic_payload
> > > *payload)
> > > >  {
> > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > +   u8 time_slots_to_remove;
> > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > +
> > > > +   /* Find the current allocated time slot number of the payload */
> > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > +           if (pos != payload &&
> > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > +   }
> > > > +
> > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > +payload->vc_start_slot;
> > > 
> > > Imo, the intuitive way would be to pass the old payload state to this function -
> > > which already contains the required time_slots param - and refactor things
> > > instead moving vc_start_slot from the payload state to mgr suggested by Ville
> > > earlier.
> > > 
> > > --Imre
> > 
> > Hi Imre,
> > Thanks for your feedback!
> > 
> > I understand it's functionally correct. But IMHO, it's still a bit
> > conceptually different between the time slot in old state and the time
> > slot in current payload table. My thought is the time slot at the
> > moment when we are removing the payload would be a better choice.
> 
> Yes, they are different. The old state contains the time slot the
> payload was added with in a preceding commit and so the time slot value
> which should be used when removing the same payload in the current
> commit.
> 
> The new state contains a time slot value with which the payload will be
> added in the current commit and can be different than the one in the old
> state if the current commit has changed the payload size (meaning that
> the same atomic commit will first remove the payload using the time slot
> value in the old state and afterwards will add back the same payload
> using the time slot value in the new state).
> 
> > And with this, we can also simplify some codes. Especially remove
> > workaround in amd driver. In fact, DRM mst code maintains the payload
> > table and all the time slot info is in it already. We don't really
> > have to pass a new parameter.
> 
> I agree that drm_dp_remove_payload() could be simplified, but this
> should be done so that the drivers can pass the old payload state to it
> (without having to pass the new state). This would be possible if
> vc_start_slot was not tracked in the payload state (which is really not
> an atomic state that can be precomputed as all other atomic state),
> rather it would be tracked in struct drm_dp_mst_topology_mgr.

JFYI too  - I think I'm fine with us moving vc_start_slot elsewhere at this
point ;)

> 
> It looks like AMD has to reconstruct the old state in
> dm_helpers_construct_old_payload(). Could you explain why it couldn't
> instead just pass old_payload acquired by
> 
> old_mst_state = drm_atomic_get_old_mst_topology_state();
> old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> 
> ?
> 
> > > >     /* Remove local payload allocation */
> > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > > vc_start_slot)
> > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > +           if (pos != payload && pos->vc_start_slot > payload-
> > > > vc_start_slot)
> > > > +                   pos->vc_start_slot -= time_slots_to_remove;
> > > >     }
> > > > -   new_payload->vc_start_slot = -1;
> > > > +   payload->vc_start_slot = -1;
> > > > 
> > > >     mgr->payload_count--;
> > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > 
> > > > -   if (new_payload->delete)
> > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > +   if (payload->delete)
> > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > > 
> > > > -   new_payload->payload_allocation_status =
> > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > +   payload->payload_allocation_status =
> > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > >  }
> > 
> > --
> > Regards,
> > Wayne
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-08-08  3:47           ` Lin, Wayne
@ 2023-08-18 17:46             ` Imre Deak
  -1 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-08-18 17:46 UTC (permalink / raw)
  To: Lin, Wayne; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> [AMD Official Use Only - General]
> 
> > -----Original Message-----
> > From: Imre Deak <imre.deak@intel.com>
> > Sent: Tuesday, August 8, 2023 12:00 AM
> > To: Lin, Wayne <Wayne.Lin@amd.com>
> > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > <Jerry.Zuo@amd.com>
> > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > drm_dp_remove_payload_part2()
> >
> > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > [AMD Official Use Only - General]
> > >
> > > > -----Original Message-----
> > > > From: Imre Deak <imre.deak@intel.com>
> > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > > lyude@redhat.com; jani.nikula@intel.com;
> > > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > drm_dp_remove_payload_part2()
> > > >
> > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > [...]
> > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > @@ -3382,8 +3382,7 @@
> > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > >   * drm_dp_remove_payload_part2() - Remove an MST payload locally
> > > > >   * @mgr: Manager to use.
> > > > >   * @mst_state: The MST atomic state
> > > > > - * @old_payload: The payload with its old state
> > > > > - * @new_payload: The payload with its latest state
> > > > > + * @payload: The payload with its latest state
> > > > >   *
> > > > >   * Updates the starting time slots of all other payloads which
> > > > > would have
> > > > been shifted towards
> > > > >   * the start of the payload ID table as a result of removing a
> > > > > payload. Driver should call this @@ -3392,25 +3391,36 @@
> > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > >   */
> > > > >  void drm_dp_remove_payload_part2(struct
> > drm_dp_mst_topology_mgr
> > > > *mgr,
> > > > >                              struct drm_dp_mst_topology_state
> > > > *mst_state,
> > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > *old_payload,
> > > > > -                            struct drm_dp_mst_atomic_payload
> > > > *new_payload)
> > > > > +                            struct drm_dp_mst_atomic_payload
> > > > *payload)
> > > > >  {
> > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > +   u8 time_slots_to_remove;
> > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > +
> > > > > +   /* Find the current allocated time slot number of the payload */
> > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > +           if (pos != payload &&
> > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > +   }
> > > > > +
> > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > +payload->vc_start_slot;
> > > >
> > > > Imo, the intuitive way would be to pass the old payload state to
> > > > this function - which already contains the required time_slots param
> > > > - and refactor things instead moving vc_start_slot from the payload
> > > > state to mgr suggested by Ville earlier.
> > > >
> > > > --Imre
> > >
> > > Hi Imre,
> > > Thanks for your feedback!
> > >
> > > I understand it's functionally correct. But IMHO, it's still a bit
> > > conceptually different between the time slot in old state and the time
> > > slot in current payload table. My thought is the time slot at the
> > > moment when we are removing the payload would be a better choice.
> >
> > Yes, they are different. The old state contains the time slot the payload was
> > added with in a preceding commit and so the time slot value which should be
> > used when removing the same payload in the current commit.
> >
> > The new state contains a time slot value with which the payload will be added
> > in the current commit and can be different than the one in the old state if the
> > current commit has changed the payload size (meaning that the same atomic
> > commit will first remove the payload using the time slot value in the old state
> > and afterwards will add back the same payload using the time slot value in the
> > new state).
> >
> Appreciate your time, Imre!
> 
> Yes I understand, so I'm not using the number of the time slot in the new state.
> I'm referring to the start slot instead which is updated during every allocation
> and removement at current commit.
> 
> Like what you said, current commit manipulation could be a mix of allocations
> and removements for the payload. My thought is, conceptually, looking up the
> latest number of time slot is a better choice rather than the one in old state.
> It's relatively intuitive to me since we are removing payload from current
> payload table and which changes since last preceding commit till the moment
> we're deleting the payload. Although it's unreasonable that these values are
> different.
> 
> > > And with this, we can also simplify some codes. Especially remove
> > > workaround in amd driver. In fact, DRM mst code maintains the payload
> > > table and all the time slot info is in it already. We don't really
> > > have to pass a new parameter.
> >
> > I agree that drm_dp_remove_payload() could be simplified, but this should be
> > done so that the drivers can pass the old payload state to it (without having to
> > pass the new state). This would be possible if vc_start_slot was not tracked in
> > the payload state (which is really not an atomic state that can be precomputed
> > as all other atomic state), rather it would be tracked in struct
> > drm_dp_mst_topology_mgr.
> >
> 
> So the reason I chose to pass the new state is like what I mentioned above. I
> would prefer to carry the latest updated payload table instead which is in the new
> state. And I agree with the explanation for the vc_start_slot and that's also my
> thought at the beginning. It could be a refactor later, but no matter the start slot
> is put into payload state or the topology manager I would prefer to refer to the
> latest payload table rather than the number of time slot in the old state.
> 
> > It looks like AMD has to reconstruct the old state in
> > dm_helpers_construct_old_payload(). Could you explain why it couldn't
> > instead just pass old_payload acquired by
> >
> > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> >
> > ?
> 
> AMD doesn't pass the drm old state to the stage while HW is deleting
> the payload.  The reason is that HW payload table is known during HW
> programming procedure, so the payload removement is based on the table
> at the moment.
>
> AMD expected the current number of time slot is also
> already maintained in drm layer.

Yes, both of the above are maintained by the drm layer, but it also
means it doesn't really need to recalculate time_slots_to_remove as done
in this patch, since that info is already available in the old payload
state.

Afaics the AMD driver calls properly 

drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()

after a commit, so that all the payloads it added should be tracked
now as the old payload state.

So could you confirm what is the old_payload->time_slots value (which
you get with the above functions) at the point of removing this payload
and if it's not the time_slots value this same payload was actually
added with previously, why this is so (via some example sequence)?

Thanks.

> Again, thanks for your feedback Imre!
> 
> >
> > > > >     /* Remove local payload allocation */
> > > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > > >vc_start_slot)
> > > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > > +           if (pos != payload && pos->vc_start_slot > payload-
> > > > >vc_start_slot)
> > > > > +                   pos->vc_start_slot -= time_slots_to_remove;
> > > > >     }
> > > > > -   new_payload->vc_start_slot = -1;
> > > > > +   payload->vc_start_slot = -1;
> > > > >
> > > > >     mgr->payload_count--;
> > > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > >
> > > > > -   if (new_payload->delete)
> > > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > > +   if (payload->delete)
> > > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > > >
> > > > > -   new_payload->payload_allocation_status =
> > > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > +   payload->payload_allocation_status =
> > > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > >  }
> > >
> > > --
> > > Regards,
> > > Wayne
> 
> --
> Regards,
> Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-08-18 17:46             ` Imre Deak
  0 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-08-18 17:46 UTC (permalink / raw)
  To: Lin, Wayne
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> [AMD Official Use Only - General]
> 
> > -----Original Message-----
> > From: Imre Deak <imre.deak@intel.com>
> > Sent: Tuesday, August 8, 2023 12:00 AM
> > To: Lin, Wayne <Wayne.Lin@amd.com>
> > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > <Jerry.Zuo@amd.com>
> > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > drm_dp_remove_payload_part2()
> >
> > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > [AMD Official Use Only - General]
> > >
> > > > -----Original Message-----
> > > > From: Imre Deak <imre.deak@intel.com>
> > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > > lyude@redhat.com; jani.nikula@intel.com;
> > > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > drm_dp_remove_payload_part2()
> > > >
> > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > [...]
> > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > @@ -3382,8 +3382,7 @@
> > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > >   * drm_dp_remove_payload_part2() - Remove an MST payload locally
> > > > >   * @mgr: Manager to use.
> > > > >   * @mst_state: The MST atomic state
> > > > > - * @old_payload: The payload with its old state
> > > > > - * @new_payload: The payload with its latest state
> > > > > + * @payload: The payload with its latest state
> > > > >   *
> > > > >   * Updates the starting time slots of all other payloads which
> > > > > would have
> > > > been shifted towards
> > > > >   * the start of the payload ID table as a result of removing a
> > > > > payload. Driver should call this @@ -3392,25 +3391,36 @@
> > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > >   */
> > > > >  void drm_dp_remove_payload_part2(struct
> > drm_dp_mst_topology_mgr
> > > > *mgr,
> > > > >                              struct drm_dp_mst_topology_state
> > > > *mst_state,
> > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > *old_payload,
> > > > > -                            struct drm_dp_mst_atomic_payload
> > > > *new_payload)
> > > > > +                            struct drm_dp_mst_atomic_payload
> > > > *payload)
> > > > >  {
> > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > +   u8 time_slots_to_remove;
> > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > +
> > > > > +   /* Find the current allocated time slot number of the payload */
> > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > +           if (pos != payload &&
> > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > +   }
> > > > > +
> > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > +payload->vc_start_slot;
> > > >
> > > > Imo, the intuitive way would be to pass the old payload state to
> > > > this function - which already contains the required time_slots param
> > > > - and refactor things instead moving vc_start_slot from the payload
> > > > state to mgr suggested by Ville earlier.
> > > >
> > > > --Imre
> > >
> > > Hi Imre,
> > > Thanks for your feedback!
> > >
> > > I understand it's functionally correct. But IMHO, it's still a bit
> > > conceptually different between the time slot in old state and the time
> > > slot in current payload table. My thought is the time slot at the
> > > moment when we are removing the payload would be a better choice.
> >
> > Yes, they are different. The old state contains the time slot the payload was
> > added with in a preceding commit and so the time slot value which should be
> > used when removing the same payload in the current commit.
> >
> > The new state contains a time slot value with which the payload will be added
> > in the current commit and can be different than the one in the old state if the
> > current commit has changed the payload size (meaning that the same atomic
> > commit will first remove the payload using the time slot value in the old state
> > and afterwards will add back the same payload using the time slot value in the
> > new state).
> >
> Appreciate your time, Imre!
> 
> Yes I understand, so I'm not using the number of the time slot in the new state.
> I'm referring to the start slot instead which is updated during every allocation
> and removement at current commit.
> 
> Like what you said, current commit manipulation could be a mix of allocations
> and removements for the payload. My thought is, conceptually, looking up the
> latest number of time slot is a better choice rather than the one in old state.
> It's relatively intuitive to me since we are removing payload from current
> payload table and which changes since last preceding commit till the moment
> we're deleting the payload. Although it's unreasonable that these values are
> different.
> 
> > > And with this, we can also simplify some codes. Especially remove
> > > workaround in amd driver. In fact, DRM mst code maintains the payload
> > > table and all the time slot info is in it already. We don't really
> > > have to pass a new parameter.
> >
> > I agree that drm_dp_remove_payload() could be simplified, but this should be
> > done so that the drivers can pass the old payload state to it (without having to
> > pass the new state). This would be possible if vc_start_slot was not tracked in
> > the payload state (which is really not an atomic state that can be precomputed
> > as all other atomic state), rather it would be tracked in struct
> > drm_dp_mst_topology_mgr.
> >
> 
> So the reason I chose to pass the new state is like what I mentioned above. I
> would prefer to carry the latest updated payload table instead which is in the new
> state. And I agree with the explanation for the vc_start_slot and that's also my
> thought at the beginning. It could be a refactor later, but no matter the start slot
> is put into payload state or the topology manager I would prefer to refer to the
> latest payload table rather than the number of time slot in the old state.
> 
> > It looks like AMD has to reconstruct the old state in
> > dm_helpers_construct_old_payload(). Could you explain why it couldn't
> > instead just pass old_payload acquired by
> >
> > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> >
> > ?
> 
> AMD doesn't pass the drm old state to the stage while HW is deleting
> the payload.  The reason is that HW payload table is known during HW
> programming procedure, so the payload removement is based on the table
> at the moment.
>
> AMD expected the current number of time slot is also
> already maintained in drm layer.

Yes, both of the above are maintained by the drm layer, but it also
means it doesn't really need to recalculate time_slots_to_remove as done
in this patch, since that info is already available in the old payload
state.

Afaics the AMD driver calls properly 

drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()

after a commit, so that all the payloads it added should be tracked
now as the old payload state.

So could you confirm what is the old_payload->time_slots value (which
you get with the above functions) at the point of removing this payload
and if it's not the time_slots value this same payload was actually
added with previously, why this is so (via some example sequence)?

Thanks.

> Again, thanks for your feedback Imre!
> 
> >
> > > > >     /* Remove local payload allocation */
> > > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > > >vc_start_slot)
> > > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > > +           if (pos != payload && pos->vc_start_slot > payload-
> > > > >vc_start_slot)
> > > > > +                   pos->vc_start_slot -= time_slots_to_remove;
> > > > >     }
> > > > > -   new_payload->vc_start_slot = -1;
> > > > > +   payload->vc_start_slot = -1;
> > > > >
> > > > >     mgr->payload_count--;
> > > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > >
> > > > > -   if (new_payload->delete)
> > > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > > +   if (payload->delete)
> > > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > > >
> > > > > -   new_payload->payload_allocation_status =
> > > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > +   payload->payload_allocation_status =
> > > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > >  }
> > >
> > > --
> > > Regards,
> > > Wayne
> 
> --
> Regards,
> Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-08-18 17:46             ` Imre Deak
@ 2023-08-23  3:16               ` Lin, Wayne
  -1 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-08-23  3:16 UTC (permalink / raw)
  To: imre.deak; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

[AMD Official Use Only - General]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Saturday, August 19, 2023 1:46 AM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> > [AMD Official Use Only - General]
> >
> > > -----Original Message-----
> > > From: Imre Deak <imre.deak@intel.com>
> > > Sent: Tuesday, August 8, 2023 12:00 AM
> > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > lyude@redhat.com; jani.nikula@intel.com;
> > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > drm_dp_remove_payload_part2()
> > >
> > > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > > [AMD Official Use Only - General]
> > > >
> > > > > -----Original Message-----
> > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com; Wentland,
> > > > > Harry <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > drm_dp_remove_payload_part2()
> > > > >
> > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > > [...]
> > > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > @@ -3382,8 +3382,7 @@
> > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > >   * drm_dp_remove_payload_part2() - Remove an MST payload
> locally
> > > > > >   * @mgr: Manager to use.
> > > > > >   * @mst_state: The MST atomic state
> > > > > > - * @old_payload: The payload with its old state
> > > > > > - * @new_payload: The payload with its latest state
> > > > > > + * @payload: The payload with its latest state
> > > > > >   *
> > > > > >   * Updates the starting time slots of all other payloads
> > > > > > which would have
> > > > > been shifted towards
> > > > > >   * the start of the payload ID table as a result of removing
> > > > > > a payload. Driver should call this @@ -3392,25 +3391,36 @@
> > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > >   */
> > > > > >  void drm_dp_remove_payload_part2(struct
> > > drm_dp_mst_topology_mgr
> > > > > *mgr,
> > > > > >                              struct drm_dp_mst_topology_state
> > > > > *mst_state,
> > > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > > *old_payload,
> > > > > > -                            struct drm_dp_mst_atomic_payload
> > > > > *new_payload)
> > > > > > +                            struct drm_dp_mst_atomic_payload
> > > > > *payload)
> > > > > >  {
> > > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > > +   u8 time_slots_to_remove;
> > > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > > +
> > > > > > +   /* Find the current allocated time slot number of the payload */
> > > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > +           if (pos != payload &&
> > > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > > +   }
> > > > > > +
> > > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > > +payload->vc_start_slot;
> > > > >
> > > > > Imo, the intuitive way would be to pass the old payload state to
> > > > > this function - which already contains the required time_slots
> > > > > param
> > > > > - and refactor things instead moving vc_start_slot from the
> > > > > payload state to mgr suggested by Ville earlier.
> > > > >
> > > > > --Imre
> > > >
> > > > Hi Imre,
> > > > Thanks for your feedback!
> > > >
> > > > I understand it's functionally correct. But IMHO, it's still a bit
> > > > conceptually different between the time slot in old state and the
> > > > time slot in current payload table. My thought is the time slot at
> > > > the moment when we are removing the payload would be a better
> choice.
> > >
> > > Yes, they are different. The old state contains the time slot the
> > > payload was added with in a preceding commit and so the time slot
> > > value which should be used when removing the same payload in the
> current commit.
> > >
> > > The new state contains a time slot value with which the payload will
> > > be added in the current commit and can be different than the one in
> > > the old state if the current commit has changed the payload size
> > > (meaning that the same atomic commit will first remove the payload
> > > using the time slot value in the old state and afterwards will add
> > > back the same payload using the time slot value in the new state).
> > >
> > Appreciate your time, Imre!
> >
> > Yes I understand, so I'm not using the number of the time slot in the new
> state.
> > I'm referring to the start slot instead which is updated during every
> > allocation and removement at current commit.
> >
> > Like what you said, current commit manipulation could be a mix of
> > allocations and removements for the payload. My thought is,
> > conceptually, looking up the latest number of time slot is a better choice
> rather than the one in old state.
> > It's relatively intuitive to me since we are removing payload from
> > current payload table and which changes since last preceding commit
> > till the moment we're deleting the payload. Although it's unreasonable
> > that these values are different.
> >
> > > > And with this, we can also simplify some codes. Especially remove
> > > > workaround in amd driver. In fact, DRM mst code maintains the
> > > > payload table and all the time slot info is in it already. We
> > > > don't really have to pass a new parameter.
> > >
> > > I agree that drm_dp_remove_payload() could be simplified, but this
> > > should be done so that the drivers can pass the old payload state to
> > > it (without having to pass the new state). This would be possible if
> > > vc_start_slot was not tracked in the payload state (which is really
> > > not an atomic state that can be precomputed as all other atomic
> > > state), rather it would be tracked in struct drm_dp_mst_topology_mgr.
> > >
> >
> > So the reason I chose to pass the new state is like what I mentioned
> > above. I would prefer to carry the latest updated payload table
> > instead which is in the new state. And I agree with the explanation
> > for the vc_start_slot and that's also my thought at the beginning. It
> > could be a refactor later, but no matter the start slot is put into
> > payload state or the topology manager I would prefer to refer to the latest
> payload table rather than the number of time slot in the old state.
> >
> > > It looks like AMD has to reconstruct the old state in
> > > dm_helpers_construct_old_payload(). Could you explain why it
> > > couldn't instead just pass old_payload acquired by
> > >
> > > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > > old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> > >
> > > ?
> >
> > AMD doesn't pass the drm old state to the stage while HW is deleting
> > the payload.  The reason is that HW payload table is known during HW
> > programming procedure, so the payload removement is based on the table
> > at the moment.
> >
> > AMD expected the current number of time slot is also already
> > maintained in drm layer.
>
> Yes, both of the above are maintained by the drm layer, but it also means it
> doesn't really need to recalculate time_slots_to_remove as done in this patch,
> since that info is already available in the old payload state.
>
> Afaics the AMD driver calls properly
>
> drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()
>
> after a commit, so that all the payloads it added should be tracked now as the
> old payload state.
>
> So could you confirm what is the old_payload->time_slots value (which you
> get with the above functions) at the point of removing this payload and if it's
> not the time_slots value this same payload was actually added with previously,
> why this is so (via some example sequence)?
>
> Thanks.

Hi Imre,
I'm not saying that the time_slots carried in the old state is wrong within amd driver.
But just amd driver doesn't carry the drm state to the step when it's removing the
payload, since the info is already in its hardware and drm used to maintain the info
in the drm layer. So the patch is trying to get the behavior of this helper function
back to what it used to be.

And the main reason that I want to change the pass in parameter is like what I
mentioned previously. The commit manipulation could be a mix of allocations and
removements for the payload. And in the spec, it also introduces examples to reduce
or increase the payload allocation. Although we're not using reduction/increment
today, it implicitly imposes the limitation to use them before calling the removement
helper function with the old state as the passed in parameter. So I also want to remove
the dependency by this patch. Would like to know your thoughts about this.

Thanks, Imre!

>
> > Again, thanks for your feedback Imre!
> >
> > >
> > > > > >     /* Remove local payload allocation */
> > > > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > > > >vc_start_slot)
> > > > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > > > +           if (pos != payload && pos->vc_start_slot >
> > > > > > + payload-
> > > > > >vc_start_slot)
> > > > > > +                   pos->vc_start_slot -=
> > > > > > + time_slots_to_remove;
> > > > > >     }
> > > > > > -   new_payload->vc_start_slot = -1;
> > > > > > +   payload->vc_start_slot = -1;
> > > > > >
> > > > > >     mgr->payload_count--;
> > > > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > > >
> > > > > > -   if (new_payload->delete)
> > > > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > > > +   if (payload->delete)
> > > > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > > > >
> > > > > > -   new_payload->payload_allocation_status =
> > > > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > > +   payload->payload_allocation_status =
> > > > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > >  }
> > > >
> > > > --
> > > > Regards,
> > > > Wayne
> >
> > --
> > Regards,
> > Wayne
--
Regards,
Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-08-23  3:16               ` Lin, Wayne
  0 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-08-23  3:16 UTC (permalink / raw)
  To: imre.deak
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

[AMD Official Use Only - General]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Saturday, August 19, 2023 1:46 AM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> > [AMD Official Use Only - General]
> >
> > > -----Original Message-----
> > > From: Imre Deak <imre.deak@intel.com>
> > > Sent: Tuesday, August 8, 2023 12:00 AM
> > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > lyude@redhat.com; jani.nikula@intel.com;
> > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > drm_dp_remove_payload_part2()
> > >
> > > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > > [AMD Official Use Only - General]
> > > >
> > > > > -----Original Message-----
> > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com; Wentland,
> > > > > Harry <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > drm_dp_remove_payload_part2()
> > > > >
> > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > > [...]
> > > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > @@ -3382,8 +3382,7 @@
> > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > >   * drm_dp_remove_payload_part2() - Remove an MST payload
> locally
> > > > > >   * @mgr: Manager to use.
> > > > > >   * @mst_state: The MST atomic state
> > > > > > - * @old_payload: The payload with its old state
> > > > > > - * @new_payload: The payload with its latest state
> > > > > > + * @payload: The payload with its latest state
> > > > > >   *
> > > > > >   * Updates the starting time slots of all other payloads
> > > > > > which would have
> > > > > been shifted towards
> > > > > >   * the start of the payload ID table as a result of removing
> > > > > > a payload. Driver should call this @@ -3392,25 +3391,36 @@
> > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > >   */
> > > > > >  void drm_dp_remove_payload_part2(struct
> > > drm_dp_mst_topology_mgr
> > > > > *mgr,
> > > > > >                              struct drm_dp_mst_topology_state
> > > > > *mst_state,
> > > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > > *old_payload,
> > > > > > -                            struct drm_dp_mst_atomic_payload
> > > > > *new_payload)
> > > > > > +                            struct drm_dp_mst_atomic_payload
> > > > > *payload)
> > > > > >  {
> > > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > > +   u8 time_slots_to_remove;
> > > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > > +
> > > > > > +   /* Find the current allocated time slot number of the payload */
> > > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > +           if (pos != payload &&
> > > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > > +   }
> > > > > > +
> > > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > > +payload->vc_start_slot;
> > > > >
> > > > > Imo, the intuitive way would be to pass the old payload state to
> > > > > this function - which already contains the required time_slots
> > > > > param
> > > > > - and refactor things instead moving vc_start_slot from the
> > > > > payload state to mgr suggested by Ville earlier.
> > > > >
> > > > > --Imre
> > > >
> > > > Hi Imre,
> > > > Thanks for your feedback!
> > > >
> > > > I understand it's functionally correct. But IMHO, it's still a bit
> > > > conceptually different between the time slot in old state and the
> > > > time slot in current payload table. My thought is the time slot at
> > > > the moment when we are removing the payload would be a better
> choice.
> > >
> > > Yes, they are different. The old state contains the time slot the
> > > payload was added with in a preceding commit and so the time slot
> > > value which should be used when removing the same payload in the
> current commit.
> > >
> > > The new state contains a time slot value with which the payload will
> > > be added in the current commit and can be different than the one in
> > > the old state if the current commit has changed the payload size
> > > (meaning that the same atomic commit will first remove the payload
> > > using the time slot value in the old state and afterwards will add
> > > back the same payload using the time slot value in the new state).
> > >
> > Appreciate your time, Imre!
> >
> > Yes I understand, so I'm not using the number of the time slot in the new
> state.
> > I'm referring to the start slot instead which is updated during every
> > allocation and removement at current commit.
> >
> > Like what you said, current commit manipulation could be a mix of
> > allocations and removements for the payload. My thought is,
> > conceptually, looking up the latest number of time slot is a better choice
> rather than the one in old state.
> > It's relatively intuitive to me since we are removing payload from
> > current payload table and which changes since last preceding commit
> > till the moment we're deleting the payload. Although it's unreasonable
> > that these values are different.
> >
> > > > And with this, we can also simplify some codes. Especially remove
> > > > workaround in amd driver. In fact, DRM mst code maintains the
> > > > payload table and all the time slot info is in it already. We
> > > > don't really have to pass a new parameter.
> > >
> > > I agree that drm_dp_remove_payload() could be simplified, but this
> > > should be done so that the drivers can pass the old payload state to
> > > it (without having to pass the new state). This would be possible if
> > > vc_start_slot was not tracked in the payload state (which is really
> > > not an atomic state that can be precomputed as all other atomic
> > > state), rather it would be tracked in struct drm_dp_mst_topology_mgr.
> > >
> >
> > So the reason I chose to pass the new state is like what I mentioned
> > above. I would prefer to carry the latest updated payload table
> > instead which is in the new state. And I agree with the explanation
> > for the vc_start_slot and that's also my thought at the beginning. It
> > could be a refactor later, but no matter the start slot is put into
> > payload state or the topology manager I would prefer to refer to the latest
> payload table rather than the number of time slot in the old state.
> >
> > > It looks like AMD has to reconstruct the old state in
> > > dm_helpers_construct_old_payload(). Could you explain why it
> > > couldn't instead just pass old_payload acquired by
> > >
> > > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > > old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> > >
> > > ?
> >
> > AMD doesn't pass the drm old state to the stage while HW is deleting
> > the payload.  The reason is that HW payload table is known during HW
> > programming procedure, so the payload removement is based on the table
> > at the moment.
> >
> > AMD expected the current number of time slot is also already
> > maintained in drm layer.
>
> Yes, both of the above are maintained by the drm layer, but it also means it
> doesn't really need to recalculate time_slots_to_remove as done in this patch,
> since that info is already available in the old payload state.
>
> Afaics the AMD driver calls properly
>
> drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()
>
> after a commit, so that all the payloads it added should be tracked now as the
> old payload state.
>
> So could you confirm what is the old_payload->time_slots value (which you
> get with the above functions) at the point of removing this payload and if it's
> not the time_slots value this same payload was actually added with previously,
> why this is so (via some example sequence)?
>
> Thanks.

Hi Imre,
I'm not saying that the time_slots carried in the old state is wrong within amd driver.
But just amd driver doesn't carry the drm state to the step when it's removing the
payload, since the info is already in its hardware and drm used to maintain the info
in the drm layer. So the patch is trying to get the behavior of this helper function
back to what it used to be.

And the main reason that I want to change the pass in parameter is like what I
mentioned previously. The commit manipulation could be a mix of allocations and
removements for the payload. And in the spec, it also introduces examples to reduce
or increase the payload allocation. Although we're not using reduction/increment
today, it implicitly imposes the limitation to use them before calling the removement
helper function with the old state as the passed in parameter. So I also want to remove
the dependency by this patch. Would like to know your thoughts about this.

Thanks, Imre!

>
> > Again, thanks for your feedback Imre!
> >
> > >
> > > > > >     /* Remove local payload allocation */
> > > > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > > > >vc_start_slot)
> > > > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > > > +           if (pos != payload && pos->vc_start_slot >
> > > > > > + payload-
> > > > > >vc_start_slot)
> > > > > > +                   pos->vc_start_slot -=
> > > > > > + time_slots_to_remove;
> > > > > >     }
> > > > > > -   new_payload->vc_start_slot = -1;
> > > > > > +   payload->vc_start_slot = -1;
> > > > > >
> > > > > >     mgr->payload_count--;
> > > > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > > >
> > > > > > -   if (new_payload->delete)
> > > > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > > > +   if (payload->delete)
> > > > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > > > >
> > > > > > -   new_payload->payload_allocation_status =
> > > > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > > +   payload->payload_allocation_status =
> > > > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > >  }
> > > >
> > > > --
> > > > Regards,
> > > > Wayne
> >
> > --
> > Regards,
> > Wayne
--
Regards,
Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-08-23  3:16               ` Lin, Wayne
@ 2023-08-25 13:55                 ` Imre Deak
  -1 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-08-25 13:55 UTC (permalink / raw)
  To: Lin, Wayne; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

On Wed, Aug 23, 2023 at 03:16:44AM +0000, Lin, Wayne wrote:
> [AMD Official Use Only - General]
> 
> > -----Original Message-----
> > From: Imre Deak <imre.deak@intel.com>
> > Sent: Saturday, August 19, 2023 1:46 AM
> > To: Lin, Wayne <Wayne.Lin@amd.com>
> > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > <Jerry.Zuo@amd.com>
> > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > drm_dp_remove_payload_part2()
> >
> > On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> > > [AMD Official Use Only - General]
> > >
> > > > -----Original Message-----
> > > > From: Imre Deak <imre.deak@intel.com>
> > > > Sent: Tuesday, August 8, 2023 12:00 AM
> > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > > lyude@redhat.com; jani.nikula@intel.com;
> > > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > drm_dp_remove_payload_part2()
> > > >
> > > > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > > > [AMD Official Use Only - General]
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com; Wentland,
> > > > > > Harry <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > drm_dp_remove_payload_part2()
> > > > > >
> > > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > > > [...]
> > > > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > @@ -3382,8 +3382,7 @@
> > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > >   * drm_dp_remove_payload_part2() - Remove an MST payload
> > locally
> > > > > > >   * @mgr: Manager to use.
> > > > > > >   * @mst_state: The MST atomic state
> > > > > > > - * @old_payload: The payload with its old state
> > > > > > > - * @new_payload: The payload with its latest state
> > > > > > > + * @payload: The payload with its latest state
> > > > > > >   *
> > > > > > >   * Updates the starting time slots of all other payloads
> > > > > > > which would have
> > > > > > been shifted towards
> > > > > > >   * the start of the payload ID table as a result of removing
> > > > > > > a payload. Driver should call this @@ -3392,25 +3391,36 @@
> > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > >   */
> > > > > > >  void drm_dp_remove_payload_part2(struct
> > > > drm_dp_mst_topology_mgr
> > > > > > *mgr,
> > > > > > >                              struct drm_dp_mst_topology_state
> > > > > > *mst_state,
> > > > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > > > *old_payload,
> > > > > > > -                            struct drm_dp_mst_atomic_payload
> > > > > > *new_payload)
> > > > > > > +                            struct drm_dp_mst_atomic_payload
> > > > > > *payload)
> > > > > > >  {
> > > > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > > > +   u8 time_slots_to_remove;
> > > > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > > > +
> > > > > > > +   /* Find the current allocated time slot number of the payload */
> > > > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > +           if (pos != payload &&
> > > > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > > > +   }
> > > > > > > +
> > > > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > > > +payload->vc_start_slot;
> > > > > >
> > > > > > Imo, the intuitive way would be to pass the old payload state to
> > > > > > this function - which already contains the required time_slots
> > > > > > param
> > > > > > - and refactor things instead moving vc_start_slot from the
> > > > > > payload state to mgr suggested by Ville earlier.
> > > > > >
> > > > > > --Imre
> > > > >
> > > > > Hi Imre,
> > > > > Thanks for your feedback!
> > > > >
> > > > > I understand it's functionally correct. But IMHO, it's still a bit
> > > > > conceptually different between the time slot in old state and the
> > > > > time slot in current payload table. My thought is the time slot at
> > > > > the moment when we are removing the payload would be a better
> > choice.
> > > >
> > > > Yes, they are different. The old state contains the time slot the
> > > > payload was added with in a preceding commit and so the time slot
> > > > value which should be used when removing the same payload in the
> > current commit.
> > > >
> > > > The new state contains a time slot value with which the payload will
> > > > be added in the current commit and can be different than the one in
> > > > the old state if the current commit has changed the payload size
> > > > (meaning that the same atomic commit will first remove the payload
> > > > using the time slot value in the old state and afterwards will add
> > > > back the same payload using the time slot value in the new state).
> > > >
> > > Appreciate your time, Imre!
> > >
> > > Yes I understand, so I'm not using the number of the time slot in the new
> > state.
> > > I'm referring to the start slot instead which is updated during every
> > > allocation and removement at current commit.
> > >
> > > Like what you said, current commit manipulation could be a mix of
> > > allocations and removements for the payload. My thought is,
> > > conceptually, looking up the latest number of time slot is a better choice
> > rather than the one in old state.
> > > It's relatively intuitive to me since we are removing payload from
> > > current payload table and which changes since last preceding commit
> > > till the moment we're deleting the payload. Although it's unreasonable
> > > that these values are different.
> > >
> > > > > And with this, we can also simplify some codes. Especially remove
> > > > > workaround in amd driver. In fact, DRM mst code maintains the
> > > > > payload table and all the time slot info is in it already. We
> > > > > don't really have to pass a new parameter.
> > > >
> > > > I agree that drm_dp_remove_payload() could be simplified, but this
> > > > should be done so that the drivers can pass the old payload state to
> > > > it (without having to pass the new state). This would be possible if
> > > > vc_start_slot was not tracked in the payload state (which is really
> > > > not an atomic state that can be precomputed as all other atomic
> > > > state), rather it would be tracked in struct drm_dp_mst_topology_mgr.
> > > >
> > >
> > > So the reason I chose to pass the new state is like what I mentioned
> > > above. I would prefer to carry the latest updated payload table
> > > instead which is in the new state. And I agree with the explanation
> > > for the vc_start_slot and that's also my thought at the beginning. It
> > > could be a refactor later, but no matter the start slot is put into
> > > payload state or the topology manager I would prefer to refer to the latest
> > payload table rather than the number of time slot in the old state.
> > >
> > > > It looks like AMD has to reconstruct the old state in
> > > > dm_helpers_construct_old_payload(). Could you explain why it
> > > > couldn't instead just pass old_payload acquired by
> > > >
> > > > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > > > old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> > > >
> > > > ?
> > >
> > > AMD doesn't pass the drm old state to the stage while HW is deleting
> > > the payload.  The reason is that HW payload table is known during HW
> > > programming procedure, so the payload removement is based on the table
> > > at the moment.
> > >
> > > AMD expected the current number of time slot is also already
> > > maintained in drm layer.
> >
> > Yes, both of the above are maintained by the drm layer, but it also means it
> > doesn't really need to recalculate time_slots_to_remove as done in this patch,
> > since that info is already available in the old payload state.
> >
> > Afaics the AMD driver calls properly
> >
> > drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()
> >
> > after a commit, so that all the payloads it added should be tracked now as the
> > old payload state.
> >
> > So could you confirm what is the old_payload->time_slots value (which you
> > get with the above functions) at the point of removing this payload and if it's
> > not the time_slots value this same payload was actually added with previously,
> > why this is so (via some example sequence)?
> >
> > Thanks.
> 
> Hi Imre,
> I'm not saying that the time_slots carried in the old state is wrong within amd driver.
> But just amd driver doesn't carry the drm state to the step when it's removing the
> payload, since the info is already in its hardware and drm used to maintain the info
> in the drm layer.

Hm, in 

dm_helpers_dp_mst_write_payload_allocation_table()

the

mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);

used as the new state doesn't look ok to me. The above is the MST
object's current SW state after an atomic commit/swap, but this isn't
the new state a driver should program to the HW or pass to the drm
helper functions. The object's current state could be ahead of what the
driver should program to the HW, if the driver properly implements
commit pipelining (so at the point you're programming a state you'd have
already future commits computed and queued up, each queued-up commit
with its own state).

So instead of the above mst_state the driver should pass down the
drm_atomic_state to dm_helpers_dp_mst_write_payload_allocation_table()
which should use that instead to get the MST state it should program or
pass to the drm layer.

> So the patch is trying to get the behavior of this helper function
> back to what it used to be.

The behavior before was actually broken and one reason for that was a
confusion about what's stored in the new payload state. It's a mixture of
old/current state (vc_start_slot) and new state (time_slots). So I don't
think it's a good idea to add even more dependency on this semantic.

I think the right solution for what this patch is about - remove the
need for dm_helpers_construct_old_payload(), would be to pass down
drm_atomic_state to
dm_helpers_dp_mst_write_payload_allocation_table()
based on the above.

> And the main reason that I want to change the pass in parameter is
> like what I mentioned previously. The commit manipulation could be a
> mix of allocations and removements for the payload. And in the spec,
> it also introduces examples to reduce or increase the payload
> allocation. Although we're not using reduction/increment today, it
> implicitly imposes the limitation to use them before calling the
> removement helper function with the old state as the passed in
> parameter. So I also want to remove the dependency by this patch.
> Would like to know your thoughts about this.

It's not clear what would be the benefit of changing a payload without
removing it first. In any case, I think the right direction for the
driver would be to meet the requirement to use the proper atomic state
with the drm helper functions (not the object's current SW state) as
described above.

> Thanks, Imre!
> 
> >
> > > Again, thanks for your feedback Imre!
> > >
> > > >
> > > > > > >     /* Remove local payload allocation */
> > > > > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > > > > >vc_start_slot)
> > > > > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > > > > +           if (pos != payload && pos->vc_start_slot >
> > > > > > > + payload-
> > > > > > >vc_start_slot)
> > > > > > > +                   pos->vc_start_slot -=
> > > > > > > + time_slots_to_remove;
> > > > > > >     }
> > > > > > > -   new_payload->vc_start_slot = -1;
> > > > > > > +   payload->vc_start_slot = -1;
> > > > > > >
> > > > > > >     mgr->payload_count--;
> > > > > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > > > >
> > > > > > > -   if (new_payload->delete)
> > > > > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > > > > +   if (payload->delete)
> > > > > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > > > > >
> > > > > > > -   new_payload->payload_allocation_status =
> > > > > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > > > +   payload->payload_allocation_status =
> > > > > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > > >  }
> > > > >
> > > > > --
> > > > > Regards,
> > > > > Wayne
> > >
> > > --
> > > Regards,
> > > Wayne
> --
> Regards,
> Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-08-25 13:55                 ` Imre Deak
  0 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-08-25 13:55 UTC (permalink / raw)
  To: Lin, Wayne
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

On Wed, Aug 23, 2023 at 03:16:44AM +0000, Lin, Wayne wrote:
> [AMD Official Use Only - General]
> 
> > -----Original Message-----
> > From: Imre Deak <imre.deak@intel.com>
> > Sent: Saturday, August 19, 2023 1:46 AM
> > To: Lin, Wayne <Wayne.Lin@amd.com>
> > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > <Jerry.Zuo@amd.com>
> > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > drm_dp_remove_payload_part2()
> >
> > On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> > > [AMD Official Use Only - General]
> > >
> > > > -----Original Message-----
> > > > From: Imre Deak <imre.deak@intel.com>
> > > > Sent: Tuesday, August 8, 2023 12:00 AM
> > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > > lyude@redhat.com; jani.nikula@intel.com;
> > > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > drm_dp_remove_payload_part2()
> > > >
> > > > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > > > [AMD Official Use Only - General]
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com; Wentland,
> > > > > > Harry <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > drm_dp_remove_payload_part2()
> > > > > >
> > > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > > > [...]
> > > > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > @@ -3382,8 +3382,7 @@
> > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > >   * drm_dp_remove_payload_part2() - Remove an MST payload
> > locally
> > > > > > >   * @mgr: Manager to use.
> > > > > > >   * @mst_state: The MST atomic state
> > > > > > > - * @old_payload: The payload with its old state
> > > > > > > - * @new_payload: The payload with its latest state
> > > > > > > + * @payload: The payload with its latest state
> > > > > > >   *
> > > > > > >   * Updates the starting time slots of all other payloads
> > > > > > > which would have
> > > > > > been shifted towards
> > > > > > >   * the start of the payload ID table as a result of removing
> > > > > > > a payload. Driver should call this @@ -3392,25 +3391,36 @@
> > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > >   */
> > > > > > >  void drm_dp_remove_payload_part2(struct
> > > > drm_dp_mst_topology_mgr
> > > > > > *mgr,
> > > > > > >                              struct drm_dp_mst_topology_state
> > > > > > *mst_state,
> > > > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > > > *old_payload,
> > > > > > > -                            struct drm_dp_mst_atomic_payload
> > > > > > *new_payload)
> > > > > > > +                            struct drm_dp_mst_atomic_payload
> > > > > > *payload)
> > > > > > >  {
> > > > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > > > +   u8 time_slots_to_remove;
> > > > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > > > +
> > > > > > > +   /* Find the current allocated time slot number of the payload */
> > > > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > +           if (pos != payload &&
> > > > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > > > +   }
> > > > > > > +
> > > > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > > > +payload->vc_start_slot;
> > > > > >
> > > > > > Imo, the intuitive way would be to pass the old payload state to
> > > > > > this function - which already contains the required time_slots
> > > > > > param
> > > > > > - and refactor things instead moving vc_start_slot from the
> > > > > > payload state to mgr suggested by Ville earlier.
> > > > > >
> > > > > > --Imre
> > > > >
> > > > > Hi Imre,
> > > > > Thanks for your feedback!
> > > > >
> > > > > I understand it's functionally correct. But IMHO, it's still a bit
> > > > > conceptually different between the time slot in old state and the
> > > > > time slot in current payload table. My thought is the time slot at
> > > > > the moment when we are removing the payload would be a better
> > choice.
> > > >
> > > > Yes, they are different. The old state contains the time slot the
> > > > payload was added with in a preceding commit and so the time slot
> > > > value which should be used when removing the same payload in the
> > current commit.
> > > >
> > > > The new state contains a time slot value with which the payload will
> > > > be added in the current commit and can be different than the one in
> > > > the old state if the current commit has changed the payload size
> > > > (meaning that the same atomic commit will first remove the payload
> > > > using the time slot value in the old state and afterwards will add
> > > > back the same payload using the time slot value in the new state).
> > > >
> > > Appreciate your time, Imre!
> > >
> > > Yes I understand, so I'm not using the number of the time slot in the new
> > state.
> > > I'm referring to the start slot instead which is updated during every
> > > allocation and removement at current commit.
> > >
> > > Like what you said, current commit manipulation could be a mix of
> > > allocations and removements for the payload. My thought is,
> > > conceptually, looking up the latest number of time slot is a better choice
> > rather than the one in old state.
> > > It's relatively intuitive to me since we are removing payload from
> > > current payload table and which changes since last preceding commit
> > > till the moment we're deleting the payload. Although it's unreasonable
> > > that these values are different.
> > >
> > > > > And with this, we can also simplify some codes. Especially remove
> > > > > workaround in amd driver. In fact, DRM mst code maintains the
> > > > > payload table and all the time slot info is in it already. We
> > > > > don't really have to pass a new parameter.
> > > >
> > > > I agree that drm_dp_remove_payload() could be simplified, but this
> > > > should be done so that the drivers can pass the old payload state to
> > > > it (without having to pass the new state). This would be possible if
> > > > vc_start_slot was not tracked in the payload state (which is really
> > > > not an atomic state that can be precomputed as all other atomic
> > > > state), rather it would be tracked in struct drm_dp_mst_topology_mgr.
> > > >
> > >
> > > So the reason I chose to pass the new state is like what I mentioned
> > > above. I would prefer to carry the latest updated payload table
> > > instead which is in the new state. And I agree with the explanation
> > > for the vc_start_slot and that's also my thought at the beginning. It
> > > could be a refactor later, but no matter the start slot is put into
> > > payload state or the topology manager I would prefer to refer to the latest
> > payload table rather than the number of time slot in the old state.
> > >
> > > > It looks like AMD has to reconstruct the old state in
> > > > dm_helpers_construct_old_payload(). Could you explain why it
> > > > couldn't instead just pass old_payload acquired by
> > > >
> > > > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > > > old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> > > >
> > > > ?
> > >
> > > AMD doesn't pass the drm old state to the stage while HW is deleting
> > > the payload.  The reason is that HW payload table is known during HW
> > > programming procedure, so the payload removement is based on the table
> > > at the moment.
> > >
> > > AMD expected the current number of time slot is also already
> > > maintained in drm layer.
> >
> > Yes, both of the above are maintained by the drm layer, but it also means it
> > doesn't really need to recalculate time_slots_to_remove as done in this patch,
> > since that info is already available in the old payload state.
> >
> > Afaics the AMD driver calls properly
> >
> > drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()
> >
> > after a commit, so that all the payloads it added should be tracked now as the
> > old payload state.
> >
> > So could you confirm what is the old_payload->time_slots value (which you
> > get with the above functions) at the point of removing this payload and if it's
> > not the time_slots value this same payload was actually added with previously,
> > why this is so (via some example sequence)?
> >
> > Thanks.
> 
> Hi Imre,
> I'm not saying that the time_slots carried in the old state is wrong within amd driver.
> But just amd driver doesn't carry the drm state to the step when it's removing the
> payload, since the info is already in its hardware and drm used to maintain the info
> in the drm layer.

Hm, in 

dm_helpers_dp_mst_write_payload_allocation_table()

the

mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);

used as the new state doesn't look ok to me. The above is the MST
object's current SW state after an atomic commit/swap, but this isn't
the new state a driver should program to the HW or pass to the drm
helper functions. The object's current state could be ahead of what the
driver should program to the HW, if the driver properly implements
commit pipelining (so at the point you're programming a state you'd have
already future commits computed and queued up, each queued-up commit
with its own state).

So instead of the above mst_state the driver should pass down the
drm_atomic_state to dm_helpers_dp_mst_write_payload_allocation_table()
which should use that instead to get the MST state it should program or
pass to the drm layer.

> So the patch is trying to get the behavior of this helper function
> back to what it used to be.

The behavior before was actually broken and one reason for that was a
confusion about what's stored in the new payload state. It's a mixture of
old/current state (vc_start_slot) and new state (time_slots). So I don't
think it's a good idea to add even more dependency on this semantic.

I think the right solution for what this patch is about - remove the
need for dm_helpers_construct_old_payload(), would be to pass down
drm_atomic_state to
dm_helpers_dp_mst_write_payload_allocation_table()
based on the above.

> And the main reason that I want to change the pass in parameter is
> like what I mentioned previously. The commit manipulation could be a
> mix of allocations and removements for the payload. And in the spec,
> it also introduces examples to reduce or increase the payload
> allocation. Although we're not using reduction/increment today, it
> implicitly imposes the limitation to use them before calling the
> removement helper function with the old state as the passed in
> parameter. So I also want to remove the dependency by this patch.
> Would like to know your thoughts about this.

It's not clear what would be the benefit of changing a payload without
removing it first. In any case, I think the right direction for the
driver would be to meet the requirement to use the proper atomic state
with the drm helper functions (not the object's current SW state) as
described above.

> Thanks, Imre!
> 
> >
> > > Again, thanks for your feedback Imre!
> > >
> > > >
> > > > > > >     /* Remove local payload allocation */
> > > > > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > -           if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > > > > >vc_start_slot)
> > > > > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > > > > +           if (pos != payload && pos->vc_start_slot >
> > > > > > > + payload-
> > > > > > >vc_start_slot)
> > > > > > > +                   pos->vc_start_slot -=
> > > > > > > + time_slots_to_remove;
> > > > > > >     }
> > > > > > > -   new_payload->vc_start_slot = -1;
> > > > > > > +   payload->vc_start_slot = -1;
> > > > > > >
> > > > > > >     mgr->payload_count--;
> > > > > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > > > >
> > > > > > > -   if (new_payload->delete)
> > > > > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > > > > +   if (payload->delete)
> > > > > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > > > > >
> > > > > > > -   new_payload->payload_allocation_status =
> > > > > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > > > +   payload->payload_allocation_status =
> > > > > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > > >  }
> > > > >
> > > > > --
> > > > > Regards,
> > > > > Wayne
> > >
> > > --
> > > Regards,
> > > Wayne
> --
> Regards,
> Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-08-25 13:55                 ` Imre Deak
@ 2023-09-07  3:44                   ` Lin, Wayne
  -1 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-09-07  3:44 UTC (permalink / raw)
  To: imre.deak; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

[AMD Official Use Only - General]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Friday, August 25, 2023 9:56 PM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Wed, Aug 23, 2023 at 03:16:44AM +0000, Lin, Wayne wrote:
> > [AMD Official Use Only - General]
> >
> > > -----Original Message-----
> > > From: Imre Deak <imre.deak@intel.com>
> > > Sent: Saturday, August 19, 2023 1:46 AM
> > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > lyude@redhat.com; jani.nikula@intel.com;
> > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > drm_dp_remove_payload_part2()
> > >
> > > On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> > > > [AMD Official Use Only - General]
> > > >
> > > > > -----Original Message-----
> > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > Sent: Tuesday, August 8, 2023 12:00 AM
> > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com; Wentland,
> > > > > Harry <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > drm_dp_remove_payload_part2()
> > > > >
> > > > > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > > > > [AMD Official Use Only - General]
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > > > > > > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > > > > > > <Jerry.Zuo@amd.com>
> > > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > > drm_dp_remove_payload_part2()
> > > > > > >
> > > > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > > > > [...]
> > > > > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > @@ -3382,8 +3382,7 @@
> > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > >   * drm_dp_remove_payload_part2() - Remove an MST payload
> > > locally
> > > > > > > >   * @mgr: Manager to use.
> > > > > > > >   * @mst_state: The MST atomic state
> > > > > > > > - * @old_payload: The payload with its old state
> > > > > > > > - * @new_payload: The payload with its latest state
> > > > > > > > + * @payload: The payload with its latest state
> > > > > > > >   *
> > > > > > > >   * Updates the starting time slots of all other payloads
> > > > > > > > which would have
> > > > > > > been shifted towards
> > > > > > > >   * the start of the payload ID table as a result of
> > > > > > > > removing a payload. Driver should call this @@ -3392,25
> > > > > > > > +3391,36 @@
> > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > >   */
> > > > > > > >  void drm_dp_remove_payload_part2(struct
> > > > > drm_dp_mst_topology_mgr
> > > > > > > *mgr,
> > > > > > > >                              struct
> > > > > > > > drm_dp_mst_topology_state
> > > > > > > *mst_state,
> > > > > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > > > > *old_payload,
> > > > > > > > -                            struct drm_dp_mst_atomic_payload
> > > > > > > *new_payload)
> > > > > > > > +                            struct
> > > > > > > > + drm_dp_mst_atomic_payload
> > > > > > > *payload)
> > > > > > > >  {
> > > > > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > > > > +   u8 time_slots_to_remove;
> > > > > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > > > > +
> > > > > > > > +   /* Find the current allocated time slot number of the payload */
> > > > > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > > +           if (pos != payload &&
> > > > > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > > > > +   }
> > > > > > > > +
> > > > > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > > > > +payload->vc_start_slot;
> > > > > > >
> > > > > > > Imo, the intuitive way would be to pass the old payload
> > > > > > > state to this function - which already contains the required
> > > > > > > time_slots param
> > > > > > > - and refactor things instead moving vc_start_slot from the
> > > > > > > payload state to mgr suggested by Ville earlier.
> > > > > > >
> > > > > > > --Imre
> > > > > >
> > > > > > Hi Imre,
> > > > > > Thanks for your feedback!
> > > > > >
> > > > > > I understand it's functionally correct. But IMHO, it's still a
> > > > > > bit conceptually different between the time slot in old state
> > > > > > and the time slot in current payload table. My thought is the
> > > > > > time slot at the moment when we are removing the payload would
> > > > > > be a better
> > > choice.
> > > > >
> > > > > Yes, they are different. The old state contains the time slot
> > > > > the payload was added with in a preceding commit and so the time
> > > > > slot value which should be used when removing the same payload
> > > > > in the
> > > current commit.
> > > > >
> > > > > The new state contains a time slot value with which the payload
> > > > > will be added in the current commit and can be different than
> > > > > the one in the old state if the current commit has changed the
> > > > > payload size (meaning that the same atomic commit will first
> > > > > remove the payload using the time slot value in the old state
> > > > > and afterwards will add back the same payload using the time slot value
> in the new state).
> > > > >
> > > > Appreciate your time, Imre!
> > > >
> > > > Yes I understand, so I'm not using the number of the time slot in
> > > > the new
> > > state.
> > > > I'm referring to the start slot instead which is updated during
> > > > every allocation and removement at current commit.
> > > >
> > > > Like what you said, current commit manipulation could be a mix of
> > > > allocations and removements for the payload. My thought is,
> > > > conceptually, looking up the latest number of time slot is a
> > > > better choice
> > > rather than the one in old state.
> > > > It's relatively intuitive to me since we are removing payload from
> > > > current payload table and which changes since last preceding
> > > > commit till the moment we're deleting the payload. Although it's
> > > > unreasonable that these values are different.
> > > >
> > > > > > And with this, we can also simplify some codes. Especially
> > > > > > remove workaround in amd driver. In fact, DRM mst code
> > > > > > maintains the payload table and all the time slot info is in
> > > > > > it already. We don't really have to pass a new parameter.
> > > > >
> > > > > I agree that drm_dp_remove_payload() could be simplified, but
> > > > > this should be done so that the drivers can pass the old payload
> > > > > state to it (without having to pass the new state). This would
> > > > > be possible if vc_start_slot was not tracked in the payload
> > > > > state (which is really not an atomic state that can be
> > > > > precomputed as all other atomic state), rather it would be tracked in
> struct drm_dp_mst_topology_mgr.
> > > > >
> > > >
> > > > So the reason I chose to pass the new state is like what I
> > > > mentioned above. I would prefer to carry the latest updated
> > > > payload table instead which is in the new state. And I agree with
> > > > the explanation for the vc_start_slot and that's also my thought
> > > > at the beginning. It could be a refactor later, but no matter the
> > > > start slot is put into payload state or the topology manager I
> > > > would prefer to refer to the latest
> > > payload table rather than the number of time slot in the old state.
> > > >
> > > > > It looks like AMD has to reconstruct the old state in
> > > > > dm_helpers_construct_old_payload(). Could you explain why it
> > > > > couldn't instead just pass old_payload acquired by
> > > > >
> > > > > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > > > > old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> > > > >
> > > > > ?
> > > >
> > > > AMD doesn't pass the drm old state to the stage while HW is
> > > > deleting the payload.  The reason is that HW payload table is
> > > > known during HW programming procedure, so the payload removement
> > > > is based on the table at the moment.
> > > >
> > > > AMD expected the current number of time slot is also already
> > > > maintained in drm layer.
> > >
> > > Yes, both of the above are maintained by the drm layer, but it also
> > > means it doesn't really need to recalculate time_slots_to_remove as
> > > done in this patch, since that info is already available in the old payload
> state.
> > >
> > > Afaics the AMD driver calls properly
> > >
> > > drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()
> > >
> > > after a commit, so that all the payloads it added should be tracked
> > > now as the old payload state.
> > >
> > > So could you confirm what is the old_payload->time_slots value
> > > (which you get with the above functions) at the point of removing
> > > this payload and if it's not the time_slots value this same payload
> > > was actually added with previously, why this is so (via some example
> sequence)?
> > >
> > > Thanks.
> >
> > Hi Imre,
> > I'm not saying that the time_slots carried in the old state is wrong within
> amd driver.
> > But just amd driver doesn't carry the drm state to the step when it's
> > removing the payload, since the info is already in its hardware and
> > drm used to maintain the info in the drm layer.
>
> Hm, in
>
> dm_helpers_dp_mst_write_payload_allocation_table()
>
> the
>
> mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
>
> used as the new state doesn't look ok to me. The above is the MST object's
> current SW state after an atomic commit/swap, but this isn't the new state a
> driver should program to the HW or pass to the drm helper functions. The
> object's current state could be ahead of what the driver should program to the
> HW, if the driver properly implements commit pipelining (so at the point
> you're programming a state you'd have already future commits computed and
> queued up, each queued-up commit with its own state).
>
> So instead of the above mst_state the driver should pass down the
> drm_atomic_state to dm_helpers_dp_mst_write_payload_allocation_table()
> which should use that instead to get the MST state it should program or pass
> to the drm layer.
>
> > So the patch is trying to get the behavior of this helper function
> > back to what it used to be.
>
> The behavior before was actually broken and one reason for that was a
> confusion about what's stored in the new payload state. It's a mixture of
> old/current state (vc_start_slot) and new state (time_slots). So I don't think
> it's a good idea to add even more dependency on this semantic.
>
> I think the right solution for what this patch is about - remove the need for
> dm_helpers_construct_old_payload(), would be to pass down
> drm_atomic_state to
> dm_helpers_dp_mst_write_payload_allocation_table()
> based on the above.
>
> > And the main reason that I want to change the pass in parameter is
> > like what I mentioned previously. The commit manipulation could be a
> > mix of allocations and removements for the payload. And in the spec,
> > it also introduces examples to reduce or increase the payload
> > allocation. Although we're not using reduction/increment today, it
> > implicitly imposes the limitation to use them before calling the
> > removement helper function with the old state as the passed in
> > parameter. So I also want to remove the dependency by this patch.
> > Would like to know your thoughts about this.
>
> It's not clear what would be the benefit of changing a payload without
> removing it first. In any case, I think the right direction for the driver would be
> to meet the requirement to use the proper atomic state with the drm helper
> functions (not the object's current SW state) as described above.

Hi Imre,

Thanks for pointing that out and that was also one of my plan to refactor! But I
would take that as another patch to follow up and would like to align with you
the idea for this helper function itself more.

My concern is referring to the old state to remove the time slot is just not generic
right for what the helper function shall accomplish. Even it doesn't bring benefit
as you see, having old state as the input imposes limitation to drivers using it which
is the downside that it brought. The limitation is like what I tried to explain before.
For an instance, if one driver has compressed streams allocated in the previous
commit and wants to disable these streams at the current commit. It handles and
accomplishes the commit into two steps that firstly to disable dsc engine only
(which increases the time slot), and next disable the streams. Under this design,
the old state can't represent the exact number of time slot that it want's to remove
at the moment. For this case, I don't think drm_dp_remove_payload_part2 should
block the driver to use it since the driver doesn't do things wrong.  Conversely, it's
due to the helper function constrains the driver to use an inappropriate input.

And with or without my patch, the current payload allocation table (i.e. vc_start_slot
In new state) and the time slot that this new state is going to set (i.e. time_slots in
new state) are already both in the new state. I think the patch doesn't add irrelevant
input for removing a payload as this helper function should do, because the time slot
it should remove is the exact one in the payload table now, not the one captured in
previous commit.  So in contrast, refer to old state time slot is a bit confusing to me
because it's not generic right. Would like to know your thought on this point.
Appreciate your time!

>
> > Thanks, Imre!
> >
> > >
> > > > Again, thanks for your feedback Imre!
> > > >
> > > > >
> > > > > > > >     /* Remove local payload allocation */
> > > > > > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > > -           if (pos != new_payload && pos->vc_start_slot >
> new_payload-
> > > > > > > >vc_start_slot)
> > > > > > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > > > > > +           if (pos != payload && pos->vc_start_slot >
> > > > > > > > + payload-
> > > > > > > >vc_start_slot)
> > > > > > > > +                   pos->vc_start_slot -=
> > > > > > > > + time_slots_to_remove;
> > > > > > > >     }
> > > > > > > > -   new_payload->vc_start_slot = -1;
> > > > > > > > +   payload->vc_start_slot = -1;
> > > > > > > >
> > > > > > > >     mgr->payload_count--;
> > > > > > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > > > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > > > > >
> > > > > > > > -   if (new_payload->delete)
> > > > > > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > > > > > +   if (payload->delete)
> > > > > > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > > > > > >
> > > > > > > > -   new_payload->payload_allocation_status =
> > > > > > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > > > > +   payload->payload_allocation_status =
> > > > > > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > > > >  }
> > > > > >
> > > > > > --
> > > > > > Regards,
> > > > > > Wayne
> > > >
> > > > --
> > > > Regards,
> > > > Wayne
> > --
> > Regards,
> > Wayne
--
Regards,
Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-09-07  3:44                   ` Lin, Wayne
  0 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-09-07  3:44 UTC (permalink / raw)
  To: imre.deak
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

[AMD Official Use Only - General]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Friday, August 25, 2023 9:56 PM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Wed, Aug 23, 2023 at 03:16:44AM +0000, Lin, Wayne wrote:
> > [AMD Official Use Only - General]
> >
> > > -----Original Message-----
> > > From: Imre Deak <imre.deak@intel.com>
> > > Sent: Saturday, August 19, 2023 1:46 AM
> > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > lyude@redhat.com; jani.nikula@intel.com;
> > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > drm_dp_remove_payload_part2()
> > >
> > > On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> > > > [AMD Official Use Only - General]
> > > >
> > > > > -----Original Message-----
> > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > Sent: Tuesday, August 8, 2023 12:00 AM
> > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com; Wentland,
> > > > > Harry <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > drm_dp_remove_payload_part2()
> > > > >
> > > > > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > > > > [AMD Official Use Only - General]
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > > > > > > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > > > > > > <Jerry.Zuo@amd.com>
> > > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > > drm_dp_remove_payload_part2()
> > > > > > >
> > > > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > > > > [...]
> > > > > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > @@ -3382,8 +3382,7 @@
> > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > >   * drm_dp_remove_payload_part2() - Remove an MST payload
> > > locally
> > > > > > > >   * @mgr: Manager to use.
> > > > > > > >   * @mst_state: The MST atomic state
> > > > > > > > - * @old_payload: The payload with its old state
> > > > > > > > - * @new_payload: The payload with its latest state
> > > > > > > > + * @payload: The payload with its latest state
> > > > > > > >   *
> > > > > > > >   * Updates the starting time slots of all other payloads
> > > > > > > > which would have
> > > > > > > been shifted towards
> > > > > > > >   * the start of the payload ID table as a result of
> > > > > > > > removing a payload. Driver should call this @@ -3392,25
> > > > > > > > +3391,36 @@
> > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > >   */
> > > > > > > >  void drm_dp_remove_payload_part2(struct
> > > > > drm_dp_mst_topology_mgr
> > > > > > > *mgr,
> > > > > > > >                              struct
> > > > > > > > drm_dp_mst_topology_state
> > > > > > > *mst_state,
> > > > > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > > > > *old_payload,
> > > > > > > > -                            struct drm_dp_mst_atomic_payload
> > > > > > > *new_payload)
> > > > > > > > +                            struct
> > > > > > > > + drm_dp_mst_atomic_payload
> > > > > > > *payload)
> > > > > > > >  {
> > > > > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > > > > +   u8 time_slots_to_remove;
> > > > > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > > > > +
> > > > > > > > +   /* Find the current allocated time slot number of the payload */
> > > > > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > > +           if (pos != payload &&
> > > > > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > > > > +   }
> > > > > > > > +
> > > > > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > > > > +payload->vc_start_slot;
> > > > > > >
> > > > > > > Imo, the intuitive way would be to pass the old payload
> > > > > > > state to this function - which already contains the required
> > > > > > > time_slots param
> > > > > > > - and refactor things instead moving vc_start_slot from the
> > > > > > > payload state to mgr suggested by Ville earlier.
> > > > > > >
> > > > > > > --Imre
> > > > > >
> > > > > > Hi Imre,
> > > > > > Thanks for your feedback!
> > > > > >
> > > > > > I understand it's functionally correct. But IMHO, it's still a
> > > > > > bit conceptually different between the time slot in old state
> > > > > > and the time slot in current payload table. My thought is the
> > > > > > time slot at the moment when we are removing the payload would
> > > > > > be a better
> > > choice.
> > > > >
> > > > > Yes, they are different. The old state contains the time slot
> > > > > the payload was added with in a preceding commit and so the time
> > > > > slot value which should be used when removing the same payload
> > > > > in the
> > > current commit.
> > > > >
> > > > > The new state contains a time slot value with which the payload
> > > > > will be added in the current commit and can be different than
> > > > > the one in the old state if the current commit has changed the
> > > > > payload size (meaning that the same atomic commit will first
> > > > > remove the payload using the time slot value in the old state
> > > > > and afterwards will add back the same payload using the time slot value
> in the new state).
> > > > >
> > > > Appreciate your time, Imre!
> > > >
> > > > Yes I understand, so I'm not using the number of the time slot in
> > > > the new
> > > state.
> > > > I'm referring to the start slot instead which is updated during
> > > > every allocation and removement at current commit.
> > > >
> > > > Like what you said, current commit manipulation could be a mix of
> > > > allocations and removements for the payload. My thought is,
> > > > conceptually, looking up the latest number of time slot is a
> > > > better choice
> > > rather than the one in old state.
> > > > It's relatively intuitive to me since we are removing payload from
> > > > current payload table and which changes since last preceding
> > > > commit till the moment we're deleting the payload. Although it's
> > > > unreasonable that these values are different.
> > > >
> > > > > > And with this, we can also simplify some codes. Especially
> > > > > > remove workaround in amd driver. In fact, DRM mst code
> > > > > > maintains the payload table and all the time slot info is in
> > > > > > it already. We don't really have to pass a new parameter.
> > > > >
> > > > > I agree that drm_dp_remove_payload() could be simplified, but
> > > > > this should be done so that the drivers can pass the old payload
> > > > > state to it (without having to pass the new state). This would
> > > > > be possible if vc_start_slot was not tracked in the payload
> > > > > state (which is really not an atomic state that can be
> > > > > precomputed as all other atomic state), rather it would be tracked in
> struct drm_dp_mst_topology_mgr.
> > > > >
> > > >
> > > > So the reason I chose to pass the new state is like what I
> > > > mentioned above. I would prefer to carry the latest updated
> > > > payload table instead which is in the new state. And I agree with
> > > > the explanation for the vc_start_slot and that's also my thought
> > > > at the beginning. It could be a refactor later, but no matter the
> > > > start slot is put into payload state or the topology manager I
> > > > would prefer to refer to the latest
> > > payload table rather than the number of time slot in the old state.
> > > >
> > > > > It looks like AMD has to reconstruct the old state in
> > > > > dm_helpers_construct_old_payload(). Could you explain why it
> > > > > couldn't instead just pass old_payload acquired by
> > > > >
> > > > > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > > > > old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> > > > >
> > > > > ?
> > > >
> > > > AMD doesn't pass the drm old state to the stage while HW is
> > > > deleting the payload.  The reason is that HW payload table is
> > > > known during HW programming procedure, so the payload removement
> > > > is based on the table at the moment.
> > > >
> > > > AMD expected the current number of time slot is also already
> > > > maintained in drm layer.
> > >
> > > Yes, both of the above are maintained by the drm layer, but it also
> > > means it doesn't really need to recalculate time_slots_to_remove as
> > > done in this patch, since that info is already available in the old payload
> state.
> > >
> > > Afaics the AMD driver calls properly
> > >
> > > drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()
> > >
> > > after a commit, so that all the payloads it added should be tracked
> > > now as the old payload state.
> > >
> > > So could you confirm what is the old_payload->time_slots value
> > > (which you get with the above functions) at the point of removing
> > > this payload and if it's not the time_slots value this same payload
> > > was actually added with previously, why this is so (via some example
> sequence)?
> > >
> > > Thanks.
> >
> > Hi Imre,
> > I'm not saying that the time_slots carried in the old state is wrong within
> amd driver.
> > But just amd driver doesn't carry the drm state to the step when it's
> > removing the payload, since the info is already in its hardware and
> > drm used to maintain the info in the drm layer.
>
> Hm, in
>
> dm_helpers_dp_mst_write_payload_allocation_table()
>
> the
>
> mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
>
> used as the new state doesn't look ok to me. The above is the MST object's
> current SW state after an atomic commit/swap, but this isn't the new state a
> driver should program to the HW or pass to the drm helper functions. The
> object's current state could be ahead of what the driver should program to the
> HW, if the driver properly implements commit pipelining (so at the point
> you're programming a state you'd have already future commits computed and
> queued up, each queued-up commit with its own state).
>
> So instead of the above mst_state the driver should pass down the
> drm_atomic_state to dm_helpers_dp_mst_write_payload_allocation_table()
> which should use that instead to get the MST state it should program or pass
> to the drm layer.
>
> > So the patch is trying to get the behavior of this helper function
> > back to what it used to be.
>
> The behavior before was actually broken and one reason for that was a
> confusion about what's stored in the new payload state. It's a mixture of
> old/current state (vc_start_slot) and new state (time_slots). So I don't think
> it's a good idea to add even more dependency on this semantic.
>
> I think the right solution for what this patch is about - remove the need for
> dm_helpers_construct_old_payload(), would be to pass down
> drm_atomic_state to
> dm_helpers_dp_mst_write_payload_allocation_table()
> based on the above.
>
> > And the main reason that I want to change the pass in parameter is
> > like what I mentioned previously. The commit manipulation could be a
> > mix of allocations and removements for the payload. And in the spec,
> > it also introduces examples to reduce or increase the payload
> > allocation. Although we're not using reduction/increment today, it
> > implicitly imposes the limitation to use them before calling the
> > removement helper function with the old state as the passed in
> > parameter. So I also want to remove the dependency by this patch.
> > Would like to know your thoughts about this.
>
> It's not clear what would be the benefit of changing a payload without
> removing it first. In any case, I think the right direction for the driver would be
> to meet the requirement to use the proper atomic state with the drm helper
> functions (not the object's current SW state) as described above.

Hi Imre,

Thanks for pointing that out and that was also one of my plan to refactor! But I
would take that as another patch to follow up and would like to align with you
the idea for this helper function itself more.

My concern is referring to the old state to remove the time slot is just not generic
right for what the helper function shall accomplish. Even it doesn't bring benefit
as you see, having old state as the input imposes limitation to drivers using it which
is the downside that it brought. The limitation is like what I tried to explain before.
For an instance, if one driver has compressed streams allocated in the previous
commit and wants to disable these streams at the current commit. It handles and
accomplishes the commit into two steps that firstly to disable dsc engine only
(which increases the time slot), and next disable the streams. Under this design,
the old state can't represent the exact number of time slot that it want's to remove
at the moment. For this case, I don't think drm_dp_remove_payload_part2 should
block the driver to use it since the driver doesn't do things wrong.  Conversely, it's
due to the helper function constrains the driver to use an inappropriate input.

And with or without my patch, the current payload allocation table (i.e. vc_start_slot
In new state) and the time slot that this new state is going to set (i.e. time_slots in
new state) are already both in the new state. I think the patch doesn't add irrelevant
input for removing a payload as this helper function should do, because the time slot
it should remove is the exact one in the payload table now, not the one captured in
previous commit.  So in contrast, refer to old state time slot is a bit confusing to me
because it's not generic right. Would like to know your thought on this point.
Appreciate your time!

>
> > Thanks, Imre!
> >
> > >
> > > > Again, thanks for your feedback Imre!
> > > >
> > > > >
> > > > > > > >     /* Remove local payload allocation */
> > > > > > > >     list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > > -           if (pos != new_payload && pos->vc_start_slot >
> new_payload-
> > > > > > > >vc_start_slot)
> > > > > > > > -                   pos->vc_start_slot -= old_payload->time_slots;
> > > > > > > > +           if (pos != payload && pos->vc_start_slot >
> > > > > > > > + payload-
> > > > > > > >vc_start_slot)
> > > > > > > > +                   pos->vc_start_slot -=
> > > > > > > > + time_slots_to_remove;
> > > > > > > >     }
> > > > > > > > -   new_payload->vc_start_slot = -1;
> > > > > > > > +   payload->vc_start_slot = -1;
> > > > > > > >
> > > > > > > >     mgr->payload_count--;
> > > > > > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > > > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > > > > >
> > > > > > > > -   if (new_payload->delete)
> > > > > > > > -           drm_dp_mst_put_port_malloc(new_payload->port);
> > > > > > > > +   if (payload->delete)
> > > > > > > > +           drm_dp_mst_put_port_malloc(payload->port);
> > > > > > > >
> > > > > > > > -   new_payload->payload_allocation_status =
> > > > > > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > > > > +   payload->payload_allocation_status =
> > > > > > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > > > > >  }
> > > > > >
> > > > > > --
> > > > > > Regards,
> > > > > > Wayne
> > > >
> > > > --
> > > > Regards,
> > > > Wayne
> > --
> > Regards,
> > Wayne
--
Regards,
Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-09-07  3:44                   ` Lin, Wayne
@ 2023-09-08 19:18                     ` Imre Deak
  -1 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-09-08 19:18 UTC (permalink / raw)
  To: Lin, Wayne; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

On Thu, Sep 07, 2023 at 03:44:39AM +0000, Lin, Wayne wrote:
> [AMD Official Use Only - General]
> 
> > -----Original Message-----
> > From: Imre Deak <imre.deak@intel.com>
> > Sent: Friday, August 25, 2023 9:56 PM
> > To: Lin, Wayne <Wayne.Lin@amd.com>
> > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > <Jerry.Zuo@amd.com>
> > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > drm_dp_remove_payload_part2()
> >
> > On Wed, Aug 23, 2023 at 03:16:44AM +0000, Lin, Wayne wrote:
> > > [AMD Official Use Only - General]
> > >
> > > > -----Original Message-----
> > > > From: Imre Deak <imre.deak@intel.com>
> > > > Sent: Saturday, August 19, 2023 1:46 AM
> > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > > lyude@redhat.com; jani.nikula@intel.com;
> > > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > drm_dp_remove_payload_part2()
> > > >
> > > > On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> > > > > [AMD Official Use Only - General]
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > Sent: Tuesday, August 8, 2023 12:00 AM
> > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com; Wentland,
> > > > > > Harry <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > drm_dp_remove_payload_part2()
> > > > > >
> > > > > > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > > > > > [AMD Official Use Only - General]
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > > > > > > > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > > > > > > > <Jerry.Zuo@amd.com>
> > > > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > > > drm_dp_remove_payload_part2()
> > > > > > > >
> > > > > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > > > > > [...]
> > > > > > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > @@ -3382,8 +3382,7 @@
> > > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > > >   * drm_dp_remove_payload_part2() - Remove an MST payload
> > > > locally
> > > > > > > > >   * @mgr: Manager to use.
> > > > > > > > >   * @mst_state: The MST atomic state
> > > > > > > > > - * @old_payload: The payload with its old state
> > > > > > > > > - * @new_payload: The payload with its latest state
> > > > > > > > > + * @payload: The payload with its latest state
> > > > > > > > >   *
> > > > > > > > >   * Updates the starting time slots of all other payloads
> > > > > > > > > which would have
> > > > > > > > been shifted towards
> > > > > > > > >   * the start of the payload ID table as a result of
> > > > > > > > > removing a payload. Driver should call this @@ -3392,25
> > > > > > > > > +3391,36 @@
> > > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > > >   */
> > > > > > > > >  void drm_dp_remove_payload_part2(struct
> > > > > > drm_dp_mst_topology_mgr
> > > > > > > > *mgr,
> > > > > > > > >                              struct
> > > > > > > > > drm_dp_mst_topology_state
> > > > > > > > *mst_state,
> > > > > > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > > > > > *old_payload,
> > > > > > > > > -                            struct drm_dp_mst_atomic_payload
> > > > > > > > *new_payload)
> > > > > > > > > +                            struct
> > > > > > > > > + drm_dp_mst_atomic_payload
> > > > > > > > *payload)
> > > > > > > > >  {
> > > > > > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > > > > > +   u8 time_slots_to_remove;
> > > > > > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > > > > > +
> > > > > > > > > +   /* Find the current allocated time slot number of the payload */
> > > > > > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > > > +           if (pos != payload &&
> > > > > > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > > > > > +   }
> > > > > > > > > +
> > > > > > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > > > > > +payload->vc_start_slot;
> > > > > > > >
> > > > > > > > Imo, the intuitive way would be to pass the old payload
> > > > > > > > state to this function - which already contains the required
> > > > > > > > time_slots param
> > > > > > > > - and refactor things instead moving vc_start_slot from the
> > > > > > > > payload state to mgr suggested by Ville earlier.
> > > > > > > >
> > > > > > > > --Imre
> > > > > > >
> > > > > > > Hi Imre,
> > > > > > > Thanks for your feedback!
> > > > > > >
> > > > > > > I understand it's functionally correct. But IMHO, it's still a
> > > > > > > bit conceptually different between the time slot in old state
> > > > > > > and the time slot in current payload table. My thought is the
> > > > > > > time slot at the moment when we are removing the payload would
> > > > > > > be a better
> > > > choice.
> > > > > >
> > > > > > Yes, they are different. The old state contains the time slot
> > > > > > the payload was added with in a preceding commit and so the time
> > > > > > slot value which should be used when removing the same payload
> > > > > > in the
> > > > current commit.
> > > > > >
> > > > > > The new state contains a time slot value with which the payload
> > > > > > will be added in the current commit and can be different than
> > > > > > the one in the old state if the current commit has changed the
> > > > > > payload size (meaning that the same atomic commit will first
> > > > > > remove the payload using the time slot value in the old state
> > > > > > and afterwards will add back the same payload using the time slot value
> > in the new state).
> > > > > >
> > > > > Appreciate your time, Imre!
> > > > >
> > > > > Yes I understand, so I'm not using the number of the time slot in
> > > > > the new
> > > > state.
> > > > > I'm referring to the start slot instead which is updated during
> > > > > every allocation and removement at current commit.
> > > > >
> > > > > Like what you said, current commit manipulation could be a mix of
> > > > > allocations and removements for the payload. My thought is,
> > > > > conceptually, looking up the latest number of time slot is a
> > > > > better choice
> > > > rather than the one in old state.
> > > > > It's relatively intuitive to me since we are removing payload from
> > > > > current payload table and which changes since last preceding
> > > > > commit till the moment we're deleting the payload. Although it's
> > > > > unreasonable that these values are different.
> > > > >
> > > > > > > And with this, we can also simplify some codes. Especially
> > > > > > > remove workaround in amd driver. In fact, DRM mst code
> > > > > > > maintains the payload table and all the time slot info is in
> > > > > > > it already. We don't really have to pass a new parameter.
> > > > > >
> > > > > > I agree that drm_dp_remove_payload() could be simplified, but
> > > > > > this should be done so that the drivers can pass the old payload
> > > > > > state to it (without having to pass the new state). This would
> > > > > > be possible if vc_start_slot was not tracked in the payload
> > > > > > state (which is really not an atomic state that can be
> > > > > > precomputed as all other atomic state), rather it would be tracked in
> > struct drm_dp_mst_topology_mgr.
> > > > > >
> > > > >
> > > > > So the reason I chose to pass the new state is like what I
> > > > > mentioned above. I would prefer to carry the latest updated
> > > > > payload table instead which is in the new state. And I agree with
> > > > > the explanation for the vc_start_slot and that's also my thought
> > > > > at the beginning. It could be a refactor later, but no matter the
> > > > > start slot is put into payload state or the topology manager I
> > > > > would prefer to refer to the latest
> > > > payload table rather than the number of time slot in the old state.
> > > > >
> > > > > > It looks like AMD has to reconstruct the old state in
> > > > > > dm_helpers_construct_old_payload(). Could you explain why it
> > > > > > couldn't instead just pass old_payload acquired by
> > > > > >
> > > > > > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > > > > > old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> > > > > >
> > > > > > ?
> > > > >
> > > > > AMD doesn't pass the drm old state to the stage while HW is
> > > > > deleting the payload.  The reason is that HW payload table is
> > > > > known during HW programming procedure, so the payload removement
> > > > > is based on the table at the moment.
> > > > >
> > > > > AMD expected the current number of time slot is also already
> > > > > maintained in drm layer.
> > > >
> > > > Yes, both of the above are maintained by the drm layer, but it also
> > > > means it doesn't really need to recalculate time_slots_to_remove as
> > > > done in this patch, since that info is already available in the old payload
> > state.
> > > >
> > > > Afaics the AMD driver calls properly
> > > >
> > > > drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()
> > > >
> > > > after a commit, so that all the payloads it added should be tracked
> > > > now as the old payload state.
> > > >
> > > > So could you confirm what is the old_payload->time_slots value
> > > > (which you get with the above functions) at the point of removing
> > > > this payload and if it's not the time_slots value this same payload
> > > > was actually added with previously, why this is so (via some example
> > sequence)?
> > > >
> > > > Thanks.
> > >
> > > Hi Imre,
> > > I'm not saying that the time_slots carried in the old state is wrong within
> > amd driver.
> > > But just amd driver doesn't carry the drm state to the step when it's
> > > removing the payload, since the info is already in its hardware and
> > > drm used to maintain the info in the drm layer.
> >
> > Hm, in
> >
> > dm_helpers_dp_mst_write_payload_allocation_table()
> >
> > the
> >
> > mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
> >
> > used as the new state doesn't look ok to me. The above is the MST object's
> > current SW state after an atomic commit/swap, but this isn't the new state a
> > driver should program to the HW or pass to the drm helper functions. The
> > object's current state could be ahead of what the driver should program to the
> > HW, if the driver properly implements commit pipelining (so at the point
> > you're programming a state you'd have already future commits computed and
> > queued up, each queued-up commit with its own state).
> >
> > So instead of the above mst_state the driver should pass down the
> > drm_atomic_state to dm_helpers_dp_mst_write_payload_allocation_table()
> > which should use that instead to get the MST state it should program or pass
> > to the drm layer.
> >
> > > So the patch is trying to get the behavior of this helper function
> > > back to what it used to be.
> >
> > The behavior before was actually broken and one reason for that was a
> > confusion about what's stored in the new payload state. It's a mixture of
> > old/current state (vc_start_slot) and new state (time_slots). So I don't think
> > it's a good idea to add even more dependency on this semantic.
> >
> > I think the right solution for what this patch is about - remove the need for
> > dm_helpers_construct_old_payload(), would be to pass down
> > drm_atomic_state to
> > dm_helpers_dp_mst_write_payload_allocation_table()
> > based on the above.
> >
> > > And the main reason that I want to change the pass in parameter is
> > > like what I mentioned previously. The commit manipulation could be a
> > > mix of allocations and removements for the payload. And in the spec,
> > > it also introduces examples to reduce or increase the payload
> > > allocation. Although we're not using reduction/increment today, it
> > > implicitly imposes the limitation to use them before calling the
> > > removement helper function with the old state as the passed in
> > > parameter. So I also want to remove the dependency by this patch.
> > > Would like to know your thoughts about this.
> >
> > It's not clear what would be the benefit of changing a payload without
> > removing it first. In any case, I think the right direction for the driver would be
> > to meet the requirement to use the proper atomic state with the drm helper
> > functions (not the object's current SW state) as described above.
> 
> Hi Imre,
> 
> Thanks for pointing that out and that was also one of my plan to refactor! But I
> would take that as another patch to follow up and would like to align with you
> the idea for this helper function itself more.
> 
> My concern is referring to the old state to remove the time slot is just not generic
> right for what the helper function shall accomplish. Even it doesn't bring benefit
> as you see, having old state as the input imposes limitation to drivers using it which
> is the downside that it brought. The limitation is like what I tried to explain before.
> For an instance, if one driver has compressed streams allocated in the previous
> commit and wants to disable these streams at the current commit. It handles and
> accomplishes the commit into two steps that firstly to disable dsc engine only
> (which increases the time slot), and next disable the streams. Under this design,
> the old state can't represent the exact number of time slot that it want's to remove
> at the moment. For this case, I don't think drm_dp_remove_payload_part2 should
> block the driver to use it since the driver doesn't do things wrong.  Conversely, it's
> due to the helper function constrains the driver to use an inappropriate input.
> 
> And with or without my patch, the current payload allocation table (i.e. vc_start_slot
> In new state) and the time slot that this new state is going to set (i.e. time_slots in
> new state) are already both in the new state. I think the patch doesn't add irrelevant
> input for removing a payload as this helper function should do, because the time slot
> it should remove is the exact one in the payload table now, not the one captured in
> previous commit.  So in contrast, refer to old state time slot is a bit confusing to me
> because it's not generic right. Would like to know your thought on this point.
> Appreciate your time!

I'd like to be sure that the payload is removed with the size it was
added with in the previous commit and as I wrote above not depend for
this on the new payload state with a mixture of old/current/new states.
Based on that I'd be ok for instance with a new

int drm_dp_remove_port_payload(mgr, mst_state, port)

function which looks up / removes the payload with the time_slots calculated
based on the payload table as in your patch and returns the calculated
time_slots.

The AMD driver could call the above function and the current
drm_dp_remove_payload(mgr, mst_state, old_payload) function would be

	time_slots = drm_dp_remove_port_payload(mgr, mst_state, old_payload->port);
	WARN_ON(time_slots != old_payload->time_slots);

--Imre

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-09-08 19:18                     ` Imre Deak
  0 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-09-08 19:18 UTC (permalink / raw)
  To: Lin, Wayne
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

On Thu, Sep 07, 2023 at 03:44:39AM +0000, Lin, Wayne wrote:
> [AMD Official Use Only - General]
> 
> > -----Original Message-----
> > From: Imre Deak <imre.deak@intel.com>
> > Sent: Friday, August 25, 2023 9:56 PM
> > To: Lin, Wayne <Wayne.Lin@amd.com>
> > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > <Jerry.Zuo@amd.com>
> > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > drm_dp_remove_payload_part2()
> >
> > On Wed, Aug 23, 2023 at 03:16:44AM +0000, Lin, Wayne wrote:
> > > [AMD Official Use Only - General]
> > >
> > > > -----Original Message-----
> > > > From: Imre Deak <imre.deak@intel.com>
> > > > Sent: Saturday, August 19, 2023 1:46 AM
> > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > > lyude@redhat.com; jani.nikula@intel.com;
> > > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > drm_dp_remove_payload_part2()
> > > >
> > > > On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> > > > > [AMD Official Use Only - General]
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > Sent: Tuesday, August 8, 2023 12:00 AM
> > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com; Wentland,
> > > > > > Harry <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > drm_dp_remove_payload_part2()
> > > > > >
> > > > > > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > > > > > [AMD Official Use Only - General]
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > > > > > > > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > > > > > > > <Jerry.Zuo@amd.com>
> > > > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > > > drm_dp_remove_payload_part2()
> > > > > > > >
> > > > > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > > > > > [...]
> > > > > > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > @@ -3382,8 +3382,7 @@
> > > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > > >   * drm_dp_remove_payload_part2() - Remove an MST payload
> > > > locally
> > > > > > > > >   * @mgr: Manager to use.
> > > > > > > > >   * @mst_state: The MST atomic state
> > > > > > > > > - * @old_payload: The payload with its old state
> > > > > > > > > - * @new_payload: The payload with its latest state
> > > > > > > > > + * @payload: The payload with its latest state
> > > > > > > > >   *
> > > > > > > > >   * Updates the starting time slots of all other payloads
> > > > > > > > > which would have
> > > > > > > > been shifted towards
> > > > > > > > >   * the start of the payload ID table as a result of
> > > > > > > > > removing a payload. Driver should call this @@ -3392,25
> > > > > > > > > +3391,36 @@
> > > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > > >   */
> > > > > > > > >  void drm_dp_remove_payload_part2(struct
> > > > > > drm_dp_mst_topology_mgr
> > > > > > > > *mgr,
> > > > > > > > >                              struct
> > > > > > > > > drm_dp_mst_topology_state
> > > > > > > > *mst_state,
> > > > > > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > > > > > *old_payload,
> > > > > > > > > -                            struct drm_dp_mst_atomic_payload
> > > > > > > > *new_payload)
> > > > > > > > > +                            struct
> > > > > > > > > + drm_dp_mst_atomic_payload
> > > > > > > > *payload)
> > > > > > > > >  {
> > > > > > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > > > > > +   u8 time_slots_to_remove;
> > > > > > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > > > > > +
> > > > > > > > > +   /* Find the current allocated time slot number of the payload */
> > > > > > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > > > +           if (pos != payload &&
> > > > > > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > > > > > +   }
> > > > > > > > > +
> > > > > > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > > > > > +payload->vc_start_slot;
> > > > > > > >
> > > > > > > > Imo, the intuitive way would be to pass the old payload
> > > > > > > > state to this function - which already contains the required
> > > > > > > > time_slots param
> > > > > > > > - and refactor things instead moving vc_start_slot from the
> > > > > > > > payload state to mgr suggested by Ville earlier.
> > > > > > > >
> > > > > > > > --Imre
> > > > > > >
> > > > > > > Hi Imre,
> > > > > > > Thanks for your feedback!
> > > > > > >
> > > > > > > I understand it's functionally correct. But IMHO, it's still a
> > > > > > > bit conceptually different between the time slot in old state
> > > > > > > and the time slot in current payload table. My thought is the
> > > > > > > time slot at the moment when we are removing the payload would
> > > > > > > be a better
> > > > choice.
> > > > > >
> > > > > > Yes, they are different. The old state contains the time slot
> > > > > > the payload was added with in a preceding commit and so the time
> > > > > > slot value which should be used when removing the same payload
> > > > > > in the
> > > > current commit.
> > > > > >
> > > > > > The new state contains a time slot value with which the payload
> > > > > > will be added in the current commit and can be different than
> > > > > > the one in the old state if the current commit has changed the
> > > > > > payload size (meaning that the same atomic commit will first
> > > > > > remove the payload using the time slot value in the old state
> > > > > > and afterwards will add back the same payload using the time slot value
> > in the new state).
> > > > > >
> > > > > Appreciate your time, Imre!
> > > > >
> > > > > Yes I understand, so I'm not using the number of the time slot in
> > > > > the new
> > > > state.
> > > > > I'm referring to the start slot instead which is updated during
> > > > > every allocation and removement at current commit.
> > > > >
> > > > > Like what you said, current commit manipulation could be a mix of
> > > > > allocations and removements for the payload. My thought is,
> > > > > conceptually, looking up the latest number of time slot is a
> > > > > better choice
> > > > rather than the one in old state.
> > > > > It's relatively intuitive to me since we are removing payload from
> > > > > current payload table and which changes since last preceding
> > > > > commit till the moment we're deleting the payload. Although it's
> > > > > unreasonable that these values are different.
> > > > >
> > > > > > > And with this, we can also simplify some codes. Especially
> > > > > > > remove workaround in amd driver. In fact, DRM mst code
> > > > > > > maintains the payload table and all the time slot info is in
> > > > > > > it already. We don't really have to pass a new parameter.
> > > > > >
> > > > > > I agree that drm_dp_remove_payload() could be simplified, but
> > > > > > this should be done so that the drivers can pass the old payload
> > > > > > state to it (without having to pass the new state). This would
> > > > > > be possible if vc_start_slot was not tracked in the payload
> > > > > > state (which is really not an atomic state that can be
> > > > > > precomputed as all other atomic state), rather it would be tracked in
> > struct drm_dp_mst_topology_mgr.
> > > > > >
> > > > >
> > > > > So the reason I chose to pass the new state is like what I
> > > > > mentioned above. I would prefer to carry the latest updated
> > > > > payload table instead which is in the new state. And I agree with
> > > > > the explanation for the vc_start_slot and that's also my thought
> > > > > at the beginning. It could be a refactor later, but no matter the
> > > > > start slot is put into payload state or the topology manager I
> > > > > would prefer to refer to the latest
> > > > payload table rather than the number of time slot in the old state.
> > > > >
> > > > > > It looks like AMD has to reconstruct the old state in
> > > > > > dm_helpers_construct_old_payload(). Could you explain why it
> > > > > > couldn't instead just pass old_payload acquired by
> > > > > >
> > > > > > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > > > > > old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> > > > > >
> > > > > > ?
> > > > >
> > > > > AMD doesn't pass the drm old state to the stage while HW is
> > > > > deleting the payload.  The reason is that HW payload table is
> > > > > known during HW programming procedure, so the payload removement
> > > > > is based on the table at the moment.
> > > > >
> > > > > AMD expected the current number of time slot is also already
> > > > > maintained in drm layer.
> > > >
> > > > Yes, both of the above are maintained by the drm layer, but it also
> > > > means it doesn't really need to recalculate time_slots_to_remove as
> > > > done in this patch, since that info is already available in the old payload
> > state.
> > > >
> > > > Afaics the AMD driver calls properly
> > > >
> > > > drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()
> > > >
> > > > after a commit, so that all the payloads it added should be tracked
> > > > now as the old payload state.
> > > >
> > > > So could you confirm what is the old_payload->time_slots value
> > > > (which you get with the above functions) at the point of removing
> > > > this payload and if it's not the time_slots value this same payload
> > > > was actually added with previously, why this is so (via some example
> > sequence)?
> > > >
> > > > Thanks.
> > >
> > > Hi Imre,
> > > I'm not saying that the time_slots carried in the old state is wrong within
> > amd driver.
> > > But just amd driver doesn't carry the drm state to the step when it's
> > > removing the payload, since the info is already in its hardware and
> > > drm used to maintain the info in the drm layer.
> >
> > Hm, in
> >
> > dm_helpers_dp_mst_write_payload_allocation_table()
> >
> > the
> >
> > mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
> >
> > used as the new state doesn't look ok to me. The above is the MST object's
> > current SW state after an atomic commit/swap, but this isn't the new state a
> > driver should program to the HW or pass to the drm helper functions. The
> > object's current state could be ahead of what the driver should program to the
> > HW, if the driver properly implements commit pipelining (so at the point
> > you're programming a state you'd have already future commits computed and
> > queued up, each queued-up commit with its own state).
> >
> > So instead of the above mst_state the driver should pass down the
> > drm_atomic_state to dm_helpers_dp_mst_write_payload_allocation_table()
> > which should use that instead to get the MST state it should program or pass
> > to the drm layer.
> >
> > > So the patch is trying to get the behavior of this helper function
> > > back to what it used to be.
> >
> > The behavior before was actually broken and one reason for that was a
> > confusion about what's stored in the new payload state. It's a mixture of
> > old/current state (vc_start_slot) and new state (time_slots). So I don't think
> > it's a good idea to add even more dependency on this semantic.
> >
> > I think the right solution for what this patch is about - remove the need for
> > dm_helpers_construct_old_payload(), would be to pass down
> > drm_atomic_state to
> > dm_helpers_dp_mst_write_payload_allocation_table()
> > based on the above.
> >
> > > And the main reason that I want to change the pass in parameter is
> > > like what I mentioned previously. The commit manipulation could be a
> > > mix of allocations and removements for the payload. And in the spec,
> > > it also introduces examples to reduce or increase the payload
> > > allocation. Although we're not using reduction/increment today, it
> > > implicitly imposes the limitation to use them before calling the
> > > removement helper function with the old state as the passed in
> > > parameter. So I also want to remove the dependency by this patch.
> > > Would like to know your thoughts about this.
> >
> > It's not clear what would be the benefit of changing a payload without
> > removing it first. In any case, I think the right direction for the driver would be
> > to meet the requirement to use the proper atomic state with the drm helper
> > functions (not the object's current SW state) as described above.
> 
> Hi Imre,
> 
> Thanks for pointing that out and that was also one of my plan to refactor! But I
> would take that as another patch to follow up and would like to align with you
> the idea for this helper function itself more.
> 
> My concern is referring to the old state to remove the time slot is just not generic
> right for what the helper function shall accomplish. Even it doesn't bring benefit
> as you see, having old state as the input imposes limitation to drivers using it which
> is the downside that it brought. The limitation is like what I tried to explain before.
> For an instance, if one driver has compressed streams allocated in the previous
> commit and wants to disable these streams at the current commit. It handles and
> accomplishes the commit into two steps that firstly to disable dsc engine only
> (which increases the time slot), and next disable the streams. Under this design,
> the old state can't represent the exact number of time slot that it want's to remove
> at the moment. For this case, I don't think drm_dp_remove_payload_part2 should
> block the driver to use it since the driver doesn't do things wrong.  Conversely, it's
> due to the helper function constrains the driver to use an inappropriate input.
> 
> And with or without my patch, the current payload allocation table (i.e. vc_start_slot
> In new state) and the time slot that this new state is going to set (i.e. time_slots in
> new state) are already both in the new state. I think the patch doesn't add irrelevant
> input for removing a payload as this helper function should do, because the time slot
> it should remove is the exact one in the payload table now, not the one captured in
> previous commit.  So in contrast, refer to old state time slot is a bit confusing to me
> because it's not generic right. Would like to know your thought on this point.
> Appreciate your time!

I'd like to be sure that the payload is removed with the size it was
added with in the previous commit and as I wrote above not depend for
this on the new payload state with a mixture of old/current/new states.
Based on that I'd be ok for instance with a new

int drm_dp_remove_port_payload(mgr, mst_state, port)

function which looks up / removes the payload with the time_slots calculated
based on the payload table as in your patch and returns the calculated
time_slots.

The AMD driver could call the above function and the current
drm_dp_remove_payload(mgr, mst_state, old_payload) function would be

	time_slots = drm_dp_remove_port_payload(mgr, mst_state, old_payload->port);
	WARN_ON(time_slots != old_payload->time_slots);

--Imre

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-09-08 19:18                     ` Imre Deak
@ 2023-09-12  7:26                       ` Lin, Wayne
  -1 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-09-12  7:26 UTC (permalink / raw)
  To: imre.deak; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

[Public]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Saturday, September 9, 2023 3:18 AM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Thu, Sep 07, 2023 at 03:44:39AM +0000, Lin, Wayne wrote:
> > [AMD Official Use Only - General]
> >
> > > -----Original Message-----
> > > From: Imre Deak <imre.deak@intel.com>
> > > Sent: Friday, August 25, 2023 9:56 PM
> > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > lyude@redhat.com; jani.nikula@intel.com;
> > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > drm_dp_remove_payload_part2()
> > >
> > > On Wed, Aug 23, 2023 at 03:16:44AM +0000, Lin, Wayne wrote:
> > > > [AMD Official Use Only - General]
> > > >
> > > > > -----Original Message-----
> > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > Sent: Saturday, August 19, 2023 1:46 AM
> > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com; Wentland,
> > > > > Harry <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > drm_dp_remove_payload_part2()
> > > > >
> > > > > On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> > > > > > [AMD Official Use Only - General]
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > > Sent: Tuesday, August 8, 2023 12:00 AM
> > > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > > > > > > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > > > > > > <Jerry.Zuo@amd.com>
> > > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > > drm_dp_remove_payload_part2()
> > > > > > >
> > > > > > > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > > > > > > [AMD Official Use Only - General]
> > > > > > > >
> > > > > > > > > -----Original Message-----
> > > > > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > > > > > > > > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > > > > > > > > <Jerry.Zuo@amd.com>
> > > > > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > > > > drm_dp_remove_payload_part2()
> > > > > > > > >
> > > > > > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > > > > > > [...]
> > > > > > > > > > diff --git
> > > > > > > > > > a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > > > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > > @@ -3382,8 +3382,7 @@
> > > > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > > > >   * drm_dp_remove_payload_part2() - Remove an MST
> > > > > > > > > > payload
> > > > > locally
> > > > > > > > > >   * @mgr: Manager to use.
> > > > > > > > > >   * @mst_state: The MST atomic state
> > > > > > > > > > - * @old_payload: The payload with its old state
> > > > > > > > > > - * @new_payload: The payload with its latest state
> > > > > > > > > > + * @payload: The payload with its latest state
> > > > > > > > > >   *
> > > > > > > > > >   * Updates the starting time slots of all other
> > > > > > > > > > payloads which would have
> > > > > > > > > been shifted towards
> > > > > > > > > >   * the start of the payload ID table as a result of
> > > > > > > > > > removing a payload. Driver should call this @@
> > > > > > > > > > -3392,25
> > > > > > > > > > +3391,36 @@
> > > > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > > > >   */
> > > > > > > > > >  void drm_dp_remove_payload_part2(struct
> > > > > > > drm_dp_mst_topology_mgr
> > > > > > > > > *mgr,
> > > > > > > > > >                              struct
> > > > > > > > > > drm_dp_mst_topology_state
> > > > > > > > > *mst_state,
> > > > > > > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > > > > > > *old_payload,
> > > > > > > > > > -                            struct drm_dp_mst_atomic_payload
> > > > > > > > > *new_payload)
> > > > > > > > > > +                            struct
> > > > > > > > > > + drm_dp_mst_atomic_payload
> > > > > > > > > *payload)
> > > > > > > > > >  {
> > > > > > > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > > > > > > +   u8 time_slots_to_remove;
> > > > > > > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > > > > > > +
> > > > > > > > > > +   /* Find the current allocated time slot number of the
> payload */
> > > > > > > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > > > > +           if (pos != payload &&
> > > > > > > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > > > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > > > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > > > > > > +   }
> > > > > > > > > > +
> > > > > > > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > > > > > > +payload->vc_start_slot;
> > > > > > > > >
> > > > > > > > > Imo, the intuitive way would be to pass the old payload
> > > > > > > > > state to this function - which already contains the
> > > > > > > > > required time_slots param
> > > > > > > > > - and refactor things instead moving vc_start_slot from
> > > > > > > > > the payload state to mgr suggested by Ville earlier.
> > > > > > > > >
> > > > > > > > > --Imre
> > > > > > > >
> > > > > > > > Hi Imre,
> > > > > > > > Thanks for your feedback!
> > > > > > > >
> > > > > > > > I understand it's functionally correct. But IMHO, it's
> > > > > > > > still a bit conceptually different between the time slot
> > > > > > > > in old state and the time slot in current payload table.
> > > > > > > > My thought is the time slot at the moment when we are
> > > > > > > > removing the payload would be a better
> > > > > choice.
> > > > > > >
> > > > > > > Yes, they are different. The old state contains the time
> > > > > > > slot the payload was added with in a preceding commit and so
> > > > > > > the time slot value which should be used when removing the
> > > > > > > same payload in the
> > > > > current commit.
> > > > > > >
> > > > > > > The new state contains a time slot value with which the
> > > > > > > payload will be added in the current commit and can be
> > > > > > > different than the one in the old state if the current
> > > > > > > commit has changed the payload size (meaning that the same
> > > > > > > atomic commit will first remove the payload using the time
> > > > > > > slot value in the old state and afterwards will add back the
> > > > > > > same payload using the time slot value
> > > in the new state).
> > > > > > >
> > > > > > Appreciate your time, Imre!
> > > > > >
> > > > > > Yes I understand, so I'm not using the number of the time slot
> > > > > > in the new
> > > > > state.
> > > > > > I'm referring to the start slot instead which is updated
> > > > > > during every allocation and removement at current commit.
> > > > > >
> > > > > > Like what you said, current commit manipulation could be a mix
> > > > > > of allocations and removements for the payload. My thought is,
> > > > > > conceptually, looking up the latest number of time slot is a
> > > > > > better choice
> > > > > rather than the one in old state.
> > > > > > It's relatively intuitive to me since we are removing payload
> > > > > > from current payload table and which changes since last
> > > > > > preceding commit till the moment we're deleting the payload.
> > > > > > Although it's unreasonable that these values are different.
> > > > > >
> > > > > > > > And with this, we can also simplify some codes. Especially
> > > > > > > > remove workaround in amd driver. In fact, DRM mst code
> > > > > > > > maintains the payload table and all the time slot info is
> > > > > > > > in it already. We don't really have to pass a new parameter.
> > > > > > >
> > > > > > > I agree that drm_dp_remove_payload() could be simplified,
> > > > > > > but this should be done so that the drivers can pass the old
> > > > > > > payload state to it (without having to pass the new state).
> > > > > > > This would be possible if vc_start_slot was not tracked in
> > > > > > > the payload state (which is really not an atomic state that
> > > > > > > can be precomputed as all other atomic state), rather it
> > > > > > > would be tracked in
> > > struct drm_dp_mst_topology_mgr.
> > > > > > >
> > > > > >
> > > > > > So the reason I chose to pass the new state is like what I
> > > > > > mentioned above. I would prefer to carry the latest updated
> > > > > > payload table instead which is in the new state. And I agree
> > > > > > with the explanation for the vc_start_slot and that's also my
> > > > > > thought at the beginning. It could be a refactor later, but no
> > > > > > matter the start slot is put into payload state or the
> > > > > > topology manager I would prefer to refer to the latest
> > > > > payload table rather than the number of time slot in the old state.
> > > > > >
> > > > > > > It looks like AMD has to reconstruct the old state in
> > > > > > > dm_helpers_construct_old_payload(). Could you explain why it
> > > > > > > couldn't instead just pass old_payload acquired by
> > > > > > >
> > > > > > > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > > > > > > old_payload =
> > > > > > > drm_atomic_get_mst_payload_state(old_mst_state);
> > > > > > >
> > > > > > > ?
> > > > > >
> > > > > > AMD doesn't pass the drm old state to the stage while HW is
> > > > > > deleting the payload.  The reason is that HW payload table is
> > > > > > known during HW programming procedure, so the payload
> > > > > > removement is based on the table at the moment.
> > > > > >
> > > > > > AMD expected the current number of time slot is also already
> > > > > > maintained in drm layer.
> > > > >
> > > > > Yes, both of the above are maintained by the drm layer, but it
> > > > > also means it doesn't really need to recalculate
> > > > > time_slots_to_remove as done in this patch, since that info is
> > > > > already available in the old payload
> > > state.
> > > > >
> > > > > Afaics the AMD driver calls properly
> > > > >
> > > > > drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()
> > > > >
> > > > > after a commit, so that all the payloads it added should be
> > > > > tracked now as the old payload state.
> > > > >
> > > > > So could you confirm what is the old_payload->time_slots value
> > > > > (which you get with the above functions) at the point of
> > > > > removing this payload and if it's not the time_slots value this
> > > > > same payload was actually added with previously, why this is so
> > > > > (via some example
> > > sequence)?
> > > > >
> > > > > Thanks.
> > > >
> > > > Hi Imre,
> > > > I'm not saying that the time_slots carried in the old state is
> > > > wrong within
> > > amd driver.
> > > > But just amd driver doesn't carry the drm state to the step when
> > > > it's removing the payload, since the info is already in its
> > > > hardware and drm used to maintain the info in the drm layer.
> > >
> > > Hm, in
> > >
> > > dm_helpers_dp_mst_write_payload_allocation_table()
> > >
> > > the
> > >
> > > mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
> > >
> > > used as the new state doesn't look ok to me. The above is the MST
> > > object's current SW state after an atomic commit/swap, but this
> > > isn't the new state a driver should program to the HW or pass to the
> > > drm helper functions. The object's current state could be ahead of
> > > what the driver should program to the HW, if the driver properly
> > > implements commit pipelining (so at the point you're programming a
> > > state you'd have already future commits computed and queued up, each
> queued-up commit with its own state).
> > >
> > > So instead of the above mst_state the driver should pass down the
> > > drm_atomic_state to
> > > dm_helpers_dp_mst_write_payload_allocation_table()
> > > which should use that instead to get the MST state it should program
> > > or pass to the drm layer.
> > >
> > > > So the patch is trying to get the behavior of this helper function
> > > > back to what it used to be.
> > >
> > > The behavior before was actually broken and one reason for that was
> > > a confusion about what's stored in the new payload state. It's a
> > > mixture of old/current state (vc_start_slot) and new state
> > > (time_slots). So I don't think it's a good idea to add even more dependency
> on this semantic.
> > >
> > > I think the right solution for what this patch is about - remove the
> > > need for dm_helpers_construct_old_payload(), would be to pass down
> > > drm_atomic_state to
> > > dm_helpers_dp_mst_write_payload_allocation_table()
> > > based on the above.
> > >
> > > > And the main reason that I want to change the pass in parameter is
> > > > like what I mentioned previously. The commit manipulation could be
> > > > a mix of allocations and removements for the payload. And in the
> > > > spec, it also introduces examples to reduce or increase the
> > > > payload allocation. Although we're not using reduction/increment
> > > > today, it implicitly imposes the limitation to use them before
> > > > calling the removement helper function with the old state as the
> > > > passed in parameter. So I also want to remove the dependency by this
> patch.
> > > > Would like to know your thoughts about this.
> > >
> > > It's not clear what would be the benefit of changing a payload
> > > without removing it first. In any case, I think the right direction
> > > for the driver would be to meet the requirement to use the proper
> > > atomic state with the drm helper functions (not the object's current SW
> state) as described above.
> >
> > Hi Imre,
> >
> > Thanks for pointing that out and that was also one of my plan to
> > refactor! But I would take that as another patch to follow up and
> > would like to align with you the idea for this helper function itself more.
> >
> > My concern is referring to the old state to remove the time slot is
> > just not generic right for what the helper function shall accomplish.
> > Even it doesn't bring benefit as you see, having old state as the
> > input imposes limitation to drivers using it which is the downside that it
> brought. The limitation is like what I tried to explain before.
> > For an instance, if one driver has compressed streams allocated in the
> > previous commit and wants to disable these streams at the current
> > commit. It handles and accomplishes the commit into two steps that
> > firstly to disable dsc engine only (which increases the time slot),
> > and next disable the streams. Under this design, the old state can't
> > represent the exact number of time slot that it want's to remove at
> > the moment. For this case, I don't think drm_dp_remove_payload_part2
> > should block the driver to use it since the driver doesn't do things wrong.
> Conversely, it's due to the helper function constrains the driver to use an
> inappropriate input.
> >
> > And with or without my patch, the current payload allocation table
> > (i.e. vc_start_slot In new state) and the time slot that this new
> > state is going to set (i.e. time_slots in new state) are already both
> > in the new state. I think the patch doesn't add irrelevant input for
> > removing a payload as this helper function should do, because the time
> > slot it should remove is the exact one in the payload table now, not
> > the one captured in previous commit.  So in contrast, refer to old state time
> slot is a bit confusing to me because it's not generic right. Would like to know
> your thought on this point.
> > Appreciate your time!
>
> I'd like to be sure that the payload is removed with the size it was added with
> in the previous commit and as I wrote above not depend for this on the new
> payload state with a mixture of old/current/new states.
> Based on that I'd be ok for instance with a new
>
> int drm_dp_remove_port_payload(mgr, mst_state, port)
>
> function which looks up / removes the payload with the time_slots calculated
> based on the payload table as in your patch and returns the calculated
> time_slots.
>
> The AMD driver could call the above function and the current
> drm_dp_remove_payload(mgr, mst_state, old_payload) function would be
>
>       time_slots = drm_dp_remove_port_payload(mgr, mst_state,
> old_payload->port);
>       WARN_ON(time_slots != old_payload->time_slots);
>
> --Imre

Sorry but I might not fully understand what you suggested here. Would like to know
if you agree on referring to the time slot number of the payload table at the moment
is better then referring old_payload->time_slots for drm_dp_remove_payload()? If
you agree on that, my patch actually is just replacing old_payload->time_slots with
the more appropriate one. Not adding mixture of old/current but replacing the old
with the current one. And like what I explained in previous example, when calling
drm_dp_remove_payload(), the time slot number to be removed shouldn't be
constrained to the one in previous commit. The number in the payload table when
we're about to remove the payload might be a better choice. Could you elaborate
more what's the mixture that this patch is adding on, please?

As for the changing suggestion, are you suggesting to create a new function
drm_dp_remove_port_payload() to wrap up the calculation in my patch? If so, I think
that's the consensus to use current time slot number to replace the one in old_payload.
Therefore, it doesn't have to pass old_payload to drm_dp_remove_port_payload(), and
"WARN_ON(time_slots != old_payload->time_slots);" is not appropriate as for the
example that I gave previously.

Thanks for helping me out here.
--
Regards,
Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-09-12  7:26                       ` Lin, Wayne
  0 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-09-12  7:26 UTC (permalink / raw)
  To: imre.deak
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

[Public]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Saturday, September 9, 2023 3:18 AM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Thu, Sep 07, 2023 at 03:44:39AM +0000, Lin, Wayne wrote:
> > [AMD Official Use Only - General]
> >
> > > -----Original Message-----
> > > From: Imre Deak <imre.deak@intel.com>
> > > Sent: Friday, August 25, 2023 9:56 PM
> > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> > > lyude@redhat.com; jani.nikula@intel.com;
> > > ville.syrjala@linux.intel.com; Wentland, Harry
> > > <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > drm_dp_remove_payload_part2()
> > >
> > > On Wed, Aug 23, 2023 at 03:16:44AM +0000, Lin, Wayne wrote:
> > > > [AMD Official Use Only - General]
> > > >
> > > > > -----Original Message-----
> > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > Sent: Saturday, August 19, 2023 1:46 AM
> > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com; Wentland,
> > > > > Harry <Harry.Wentland@amd.com>; Zuo, Jerry <Jerry.Zuo@amd.com>
> > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > drm_dp_remove_payload_part2()
> > > > >
> > > > > On Tue, Aug 08, 2023 at 03:47:47AM +0000, Lin, Wayne wrote:
> > > > > > [AMD Official Use Only - General]
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > > Sent: Tuesday, August 8, 2023 12:00 AM
> > > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > > > > > > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > > > > > > <Jerry.Zuo@amd.com>
> > > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > > drm_dp_remove_payload_part2()
> > > > > > >
> > > > > > > On Mon, Aug 07, 2023 at 02:43:02AM +0000, Lin, Wayne wrote:
> > > > > > > > [AMD Official Use Only - General]
> > > > > > > >
> > > > > > > > > -----Original Message-----
> > > > > > > > > From: Imre Deak <imre.deak@intel.com>
> > > > > > > > > Sent: Friday, August 4, 2023 11:32 PM
> > > > > > > > > To: Lin, Wayne <Wayne.Lin@amd.com>
> > > > > > > > > Cc: dri-devel@lists.freedesktop.org;
> > > > > > > > > amd-gfx@lists.freedesktop.org; lyude@redhat.com;
> > > > > > > > > jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> > > > > > > > > Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> > > > > > > > > <Jerry.Zuo@amd.com>
> > > > > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> > > > > > > > > drm_dp_remove_payload_part2()
> > > > > > > > >
> > > > > > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote:
> > > > > > > > > > [...]
> > > > > > > > > > diff --git
> > > > > > > > > > a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > > index e04f87ff755a..4270178f95f6 100644
> > > > > > > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > > > > > > @@ -3382,8 +3382,7 @@
> > > > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > > > >   * drm_dp_remove_payload_part2() - Remove an MST
> > > > > > > > > > payload
> > > > > locally
> > > > > > > > > >   * @mgr: Manager to use.
> > > > > > > > > >   * @mst_state: The MST atomic state
> > > > > > > > > > - * @old_payload: The payload with its old state
> > > > > > > > > > - * @new_payload: The payload with its latest state
> > > > > > > > > > + * @payload: The payload with its latest state
> > > > > > > > > >   *
> > > > > > > > > >   * Updates the starting time slots of all other
> > > > > > > > > > payloads which would have
> > > > > > > > > been shifted towards
> > > > > > > > > >   * the start of the payload ID table as a result of
> > > > > > > > > > removing a payload. Driver should call this @@
> > > > > > > > > > -3392,25
> > > > > > > > > > +3391,36 @@
> > > > > > > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1);
> > > > > > > > > >   */
> > > > > > > > > >  void drm_dp_remove_payload_part2(struct
> > > > > > > drm_dp_mst_topology_mgr
> > > > > > > > > *mgr,
> > > > > > > > > >                              struct
> > > > > > > > > > drm_dp_mst_topology_state
> > > > > > > > > *mst_state,
> > > > > > > > > > -                            const struct drm_dp_mst_atomic_payload
> > > > > > > > > *old_payload,
> > > > > > > > > > -                            struct drm_dp_mst_atomic_payload
> > > > > > > > > *new_payload)
> > > > > > > > > > +                            struct
> > > > > > > > > > + drm_dp_mst_atomic_payload
> > > > > > > > > *payload)
> > > > > > > > > >  {
> > > > > > > > > >     struct drm_dp_mst_atomic_payload *pos;
> > > > > > > > > > +   u8 time_slots_to_remove;
> > > > > > > > > > +   u8 next_payload_vc_start = mgr->next_start_slot;
> > > > > > > > > > +
> > > > > > > > > > +   /* Find the current allocated time slot number of the
> payload */
> > > > > > > > > > +   list_for_each_entry(pos, &mst_state->payloads, next) {
> > > > > > > > > > +           if (pos != payload &&
> > > > > > > > > > +               pos->vc_start_slot > payload->vc_start_slot &&
> > > > > > > > > > +               pos->vc_start_slot < next_payload_vc_start)
> > > > > > > > > > +                   next_payload_vc_start = pos->vc_start_slot;
> > > > > > > > > > +   }
> > > > > > > > > > +
> > > > > > > > > > +   time_slots_to_remove = next_payload_vc_start -
> > > > > > > > > > +payload->vc_start_slot;
> > > > > > > > >
> > > > > > > > > Imo, the intuitive way would be to pass the old payload
> > > > > > > > > state to this function - which already contains the
> > > > > > > > > required time_slots param
> > > > > > > > > - and refactor things instead moving vc_start_slot from
> > > > > > > > > the payload state to mgr suggested by Ville earlier.
> > > > > > > > >
> > > > > > > > > --Imre
> > > > > > > >
> > > > > > > > Hi Imre,
> > > > > > > > Thanks for your feedback!
> > > > > > > >
> > > > > > > > I understand it's functionally correct. But IMHO, it's
> > > > > > > > still a bit conceptually different between the time slot
> > > > > > > > in old state and the time slot in current payload table.
> > > > > > > > My thought is the time slot at the moment when we are
> > > > > > > > removing the payload would be a better
> > > > > choice.
> > > > > > >
> > > > > > > Yes, they are different. The old state contains the time
> > > > > > > slot the payload was added with in a preceding commit and so
> > > > > > > the time slot value which should be used when removing the
> > > > > > > same payload in the
> > > > > current commit.
> > > > > > >
> > > > > > > The new state contains a time slot value with which the
> > > > > > > payload will be added in the current commit and can be
> > > > > > > different than the one in the old state if the current
> > > > > > > commit has changed the payload size (meaning that the same
> > > > > > > atomic commit will first remove the payload using the time
> > > > > > > slot value in the old state and afterwards will add back the
> > > > > > > same payload using the time slot value
> > > in the new state).
> > > > > > >
> > > > > > Appreciate your time, Imre!
> > > > > >
> > > > > > Yes I understand, so I'm not using the number of the time slot
> > > > > > in the new
> > > > > state.
> > > > > > I'm referring to the start slot instead which is updated
> > > > > > during every allocation and removement at current commit.
> > > > > >
> > > > > > Like what you said, current commit manipulation could be a mix
> > > > > > of allocations and removements for the payload. My thought is,
> > > > > > conceptually, looking up the latest number of time slot is a
> > > > > > better choice
> > > > > rather than the one in old state.
> > > > > > It's relatively intuitive to me since we are removing payload
> > > > > > from current payload table and which changes since last
> > > > > > preceding commit till the moment we're deleting the payload.
> > > > > > Although it's unreasonable that these values are different.
> > > > > >
> > > > > > > > And with this, we can also simplify some codes. Especially
> > > > > > > > remove workaround in amd driver. In fact, DRM mst code
> > > > > > > > maintains the payload table and all the time slot info is
> > > > > > > > in it already. We don't really have to pass a new parameter.
> > > > > > >
> > > > > > > I agree that drm_dp_remove_payload() could be simplified,
> > > > > > > but this should be done so that the drivers can pass the old
> > > > > > > payload state to it (without having to pass the new state).
> > > > > > > This would be possible if vc_start_slot was not tracked in
> > > > > > > the payload state (which is really not an atomic state that
> > > > > > > can be precomputed as all other atomic state), rather it
> > > > > > > would be tracked in
> > > struct drm_dp_mst_topology_mgr.
> > > > > > >
> > > > > >
> > > > > > So the reason I chose to pass the new state is like what I
> > > > > > mentioned above. I would prefer to carry the latest updated
> > > > > > payload table instead which is in the new state. And I agree
> > > > > > with the explanation for the vc_start_slot and that's also my
> > > > > > thought at the beginning. It could be a refactor later, but no
> > > > > > matter the start slot is put into payload state or the
> > > > > > topology manager I would prefer to refer to the latest
> > > > > payload table rather than the number of time slot in the old state.
> > > > > >
> > > > > > > It looks like AMD has to reconstruct the old state in
> > > > > > > dm_helpers_construct_old_payload(). Could you explain why it
> > > > > > > couldn't instead just pass old_payload acquired by
> > > > > > >
> > > > > > > old_mst_state = drm_atomic_get_old_mst_topology_state();
> > > > > > > old_payload =
> > > > > > > drm_atomic_get_mst_payload_state(old_mst_state);
> > > > > > >
> > > > > > > ?
> > > > > >
> > > > > > AMD doesn't pass the drm old state to the stage while HW is
> > > > > > deleting the payload.  The reason is that HW payload table is
> > > > > > known during HW programming procedure, so the payload
> > > > > > removement is based on the table at the moment.
> > > > > >
> > > > > > AMD expected the current number of time slot is also already
> > > > > > maintained in drm layer.
> > > > >
> > > > > Yes, both of the above are maintained by the drm layer, but it
> > > > > also means it doesn't really need to recalculate
> > > > > time_slots_to_remove as done in this patch, since that info is
> > > > > already available in the old payload
> > > state.
> > > > >
> > > > > Afaics the AMD driver calls properly
> > > > >
> > > > > drm_atomic_helper_commit() -> drm_atomic_helper_swap_state()
> > > > >
> > > > > after a commit, so that all the payloads it added should be
> > > > > tracked now as the old payload state.
> > > > >
> > > > > So could you confirm what is the old_payload->time_slots value
> > > > > (which you get with the above functions) at the point of
> > > > > removing this payload and if it's not the time_slots value this
> > > > > same payload was actually added with previously, why this is so
> > > > > (via some example
> > > sequence)?
> > > > >
> > > > > Thanks.
> > > >
> > > > Hi Imre,
> > > > I'm not saying that the time_slots carried in the old state is
> > > > wrong within
> > > amd driver.
> > > > But just amd driver doesn't carry the drm state to the step when
> > > > it's removing the payload, since the info is already in its
> > > > hardware and drm used to maintain the info in the drm layer.
> > >
> > > Hm, in
> > >
> > > dm_helpers_dp_mst_write_payload_allocation_table()
> > >
> > > the
> > >
> > > mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
> > >
> > > used as the new state doesn't look ok to me. The above is the MST
> > > object's current SW state after an atomic commit/swap, but this
> > > isn't the new state a driver should program to the HW or pass to the
> > > drm helper functions. The object's current state could be ahead of
> > > what the driver should program to the HW, if the driver properly
> > > implements commit pipelining (so at the point you're programming a
> > > state you'd have already future commits computed and queued up, each
> queued-up commit with its own state).
> > >
> > > So instead of the above mst_state the driver should pass down the
> > > drm_atomic_state to
> > > dm_helpers_dp_mst_write_payload_allocation_table()
> > > which should use that instead to get the MST state it should program
> > > or pass to the drm layer.
> > >
> > > > So the patch is trying to get the behavior of this helper function
> > > > back to what it used to be.
> > >
> > > The behavior before was actually broken and one reason for that was
> > > a confusion about what's stored in the new payload state. It's a
> > > mixture of old/current state (vc_start_slot) and new state
> > > (time_slots). So I don't think it's a good idea to add even more dependency
> on this semantic.
> > >
> > > I think the right solution for what this patch is about - remove the
> > > need for dm_helpers_construct_old_payload(), would be to pass down
> > > drm_atomic_state to
> > > dm_helpers_dp_mst_write_payload_allocation_table()
> > > based on the above.
> > >
> > > > And the main reason that I want to change the pass in parameter is
> > > > like what I mentioned previously. The commit manipulation could be
> > > > a mix of allocations and removements for the payload. And in the
> > > > spec, it also introduces examples to reduce or increase the
> > > > payload allocation. Although we're not using reduction/increment
> > > > today, it implicitly imposes the limitation to use them before
> > > > calling the removement helper function with the old state as the
> > > > passed in parameter. So I also want to remove the dependency by this
> patch.
> > > > Would like to know your thoughts about this.
> > >
> > > It's not clear what would be the benefit of changing a payload
> > > without removing it first. In any case, I think the right direction
> > > for the driver would be to meet the requirement to use the proper
> > > atomic state with the drm helper functions (not the object's current SW
> state) as described above.
> >
> > Hi Imre,
> >
> > Thanks for pointing that out and that was also one of my plan to
> > refactor! But I would take that as another patch to follow up and
> > would like to align with you the idea for this helper function itself more.
> >
> > My concern is referring to the old state to remove the time slot is
> > just not generic right for what the helper function shall accomplish.
> > Even it doesn't bring benefit as you see, having old state as the
> > input imposes limitation to drivers using it which is the downside that it
> brought. The limitation is like what I tried to explain before.
> > For an instance, if one driver has compressed streams allocated in the
> > previous commit and wants to disable these streams at the current
> > commit. It handles and accomplishes the commit into two steps that
> > firstly to disable dsc engine only (which increases the time slot),
> > and next disable the streams. Under this design, the old state can't
> > represent the exact number of time slot that it want's to remove at
> > the moment. For this case, I don't think drm_dp_remove_payload_part2
> > should block the driver to use it since the driver doesn't do things wrong.
> Conversely, it's due to the helper function constrains the driver to use an
> inappropriate input.
> >
> > And with or without my patch, the current payload allocation table
> > (i.e. vc_start_slot In new state) and the time slot that this new
> > state is going to set (i.e. time_slots in new state) are already both
> > in the new state. I think the patch doesn't add irrelevant input for
> > removing a payload as this helper function should do, because the time
> > slot it should remove is the exact one in the payload table now, not
> > the one captured in previous commit.  So in contrast, refer to old state time
> slot is a bit confusing to me because it's not generic right. Would like to know
> your thought on this point.
> > Appreciate your time!
>
> I'd like to be sure that the payload is removed with the size it was added with
> in the previous commit and as I wrote above not depend for this on the new
> payload state with a mixture of old/current/new states.
> Based on that I'd be ok for instance with a new
>
> int drm_dp_remove_port_payload(mgr, mst_state, port)
>
> function which looks up / removes the payload with the time_slots calculated
> based on the payload table as in your patch and returns the calculated
> time_slots.
>
> The AMD driver could call the above function and the current
> drm_dp_remove_payload(mgr, mst_state, old_payload) function would be
>
>       time_slots = drm_dp_remove_port_payload(mgr, mst_state,
> old_payload->port);
>       WARN_ON(time_slots != old_payload->time_slots);
>
> --Imre

Sorry but I might not fully understand what you suggested here. Would like to know
if you agree on referring to the time slot number of the payload table at the moment
is better then referring old_payload->time_slots for drm_dp_remove_payload()? If
you agree on that, my patch actually is just replacing old_payload->time_slots with
the more appropriate one. Not adding mixture of old/current but replacing the old
with the current one. And like what I explained in previous example, when calling
drm_dp_remove_payload(), the time slot number to be removed shouldn't be
constrained to the one in previous commit. The number in the payload table when
we're about to remove the payload might be a better choice. Could you elaborate
more what's the mixture that this patch is adding on, please?

As for the changing suggestion, are you suggesting to create a new function
drm_dp_remove_port_payload() to wrap up the calculation in my patch? If so, I think
that's the consensus to use current time slot number to replace the one in old_payload.
Therefore, it doesn't have to pass old_payload to drm_dp_remove_port_payload(), and
"WARN_ON(time_slots != old_payload->time_slots);" is not appropriate as for the
example that I gave previously.

Thanks for helping me out here.
--
Regards,
Wayne

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-09-12  7:26                       ` Lin, Wayne
@ 2023-09-12 11:18                         ` Imre Deak
  -1 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-09-12 11:18 UTC (permalink / raw)
  To: Lin, Wayne; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

On Tue, Sep 12, 2023 at 07:26:29AM +0000, Lin, Wayne wrote:
> [Public]
> [...]
> >
> > I'd like to be sure that the payload is removed with the size it was added with
> > in the previous commit and as I wrote above not depend for this on the new
> > payload state with a mixture of old/current/new states.
> > Based on that I'd be ok for instance with a new
> >
> > int drm_dp_remove_port_payload(mgr, mst_state, port)
> >
> > function which looks up / removes the payload with the time_slots calculated
> > based on the payload table as in your patch and returns the calculated
> > time_slots.
> >
> > The AMD driver could call the above function and the current
> > drm_dp_remove_payload(mgr, mst_state, old_payload) function would be
> >
> >       time_slots = drm_dp_remove_port_payload(mgr, mst_state,
> > old_payload->port);
> >       WARN_ON(time_slots != old_payload->time_slots);
> >
> > --Imre
> 
> Sorry but I might not fully understand what you suggested here. Would like to know
> if you agree on referring to the time slot number of the payload table at the moment
> is better then referring old_payload->time_slots for drm_dp_remove_payload()? If
> you agree on that, my patch actually is just replacing old_payload->time_slots with
> the more appropriate one. Not adding mixture of old/current but replacing the old
> with the current one. 

The new_payload state contains a mixture of old/current/new state at the
moment and this patch adds more dependency on that, recalculating the
old payload size from that state. For i915 this recalculation isn't
needed, the size is already available in the old payload state.

> And like what I explained in previous example, when calling
> drm_dp_remove_payload(), the time slot number to be removed shouldn't be
> constrained to the one in previous commit. The number in the payload table when
> we're about to remove the payload might be a better choice. Could you elaborate
> more what's the mixture that this patch is adding on, please?
>
> As for the changing suggestion, are you suggesting to create a new function
> drm_dp_remove_port_payload() to wrap up the calculation in my patch? If so, I think
> that's the consensus to use current time slot number to replace the one in old_payload.
> Therefore, it doesn't have to pass old_payload to drm_dp_remove_port_payload(), and
> "WARN_ON(time_slots != old_payload->time_slots);" is not appropriate as for the
> example that I gave previously.

I meant something like the following:

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index cbef4ff28cd8a..0555433d8050b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -343,7 +343,7 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_dp_mst_topology_state *mst_state;
 	struct drm_dp_mst_topology_mgr *mst_mgr;
-	struct drm_dp_mst_atomic_payload *new_payload, *old_payload;
+	struct drm_dp_mst_atomic_payload *new_payload;
 	enum mst_progress_status set_flag = MST_ALLOCATE_NEW_PAYLOAD;
 	enum mst_progress_status clr_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 	int ret = 0;
@@ -366,9 +366,8 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	if (enable) {
 		ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload);
 	} else {
-		dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
-						 new_payload, old_payload);
-		drm_dp_remove_payload_part2(mst_mgr, mst_state, old_payload, new_payload);
+		drm_dp_remove_current_payload_part2(mst_mgr, mst_state->base.state,
+						    aconnector->mst_output_port);
 	}
 
 	if (ret) {
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index e04f87ff755ac..4d25dba789e91 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3382,37 +3382,70 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part1);
  * drm_dp_remove_payload_part2() - Remove an MST payload locally
  * @mgr: Manager to use.
  * @mst_state: The MST atomic state
- * @old_payload: The payload with its old state
- * @new_payload: The payload with its latest state
+ * @port: MST port
  *
  * Updates the starting time slots of all other payloads which would have been shifted towards
  * the start of the payload ID table as a result of removing a payload. Driver should call this
  * function whenever it removes a payload in its HW. It's independent to the result of payload
  * allocation/deallocation at branch devices along the virtual channel.
  */
-void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
-				 struct drm_dp_mst_topology_state *mst_state,
-				 const struct drm_dp_mst_atomic_payload *old_payload,
-				 struct drm_dp_mst_atomic_payload *new_payload)
+int drm_dp_remove_current_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
+					struct drm_atomic_state *state,
+					struct drm_dp_mst_port *port)
 {
 	struct drm_dp_mst_atomic_payload *pos;
+	struct drm_dp_mst_topology_state *mst_state =
+		drm_atomic_get_new_mst_topology_state(state, mgr);
+	struct drm_dp_mst_atomic_payload *new_payload =
+		drm_atomic_get_mst_payload_state(mst_state, port);
+	int time_slots_to_remove;
+	u8 next_payload_vc_start = mgr->next_start_slot;
+
+	/* Find the current allocated time slot number of the payload */
+	list_for_each_entry(pos, &mst_state->payloads, next) {
+		if (pos != new_payload &&
+		    pos->vc_start_slot > new_payload->vc_start_slot &&
+		    pos->vc_start_slot < next_payload_vc_start)
+			next_payload_vc_start = pos->vc_start_slot;
+	}
+
+	time_slots_to_remove = next_payload_vc_start - new_payload->vc_start_slot;
 
 	/* Remove local payload allocation */
 	list_for_each_entry(pos, &mst_state->payloads, next) {
 		if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)
-			pos->vc_start_slot -= old_payload->time_slots;
+			pos->vc_start_slot -= time_slots_to_remove;
 	}
 	new_payload->vc_start_slot = -1;
 
 	mgr->payload_count--;
-	mgr->next_start_slot -= old_payload->time_slots;
+	mgr->next_start_slot -= time_slots_to_remove;
 
 	if (new_payload->delete)
 		drm_dp_mst_put_port_malloc(new_payload->port);
 
 	new_payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
+
+	return time_slots_to_remove;
+}
+EXPORT_SYMBOL(drm_dp_remove_current_payload_part2);
+
+void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
+				 struct drm_atomic_state *state,
+				 struct drm_dp_mst_port *port)
+{
+	struct drm_dp_mst_topology_state *old_mst_state =
+		drm_atomic_get_old_mst_topology_state(state, mgr);
+	struct drm_dp_mst_atomic_payload *old_payload =
+		drm_atomic_get_mst_payload_state(old_mst_state, port);
+	int time_slots;
+
+	time_slots = drm_dp_remove_current_payload_part2(mgr, state, port);
+
+	drm_WARN_ON(mgr->dev, time_slots != old_payload->time_slots);
 }
 EXPORT_SYMBOL(drm_dp_remove_payload_part2);
+
 /**
  * drm_dp_add_payload_part2() - Execute payload update part 2
  * @mgr: Manager to use.
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 1c7f0b6afe475..3ab491d9c8d27 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -576,14 +576,6 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 	struct intel_dp *intel_dp = &dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
-	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
-	struct drm_dp_mst_topology_state *new_mst_state =
-		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
-	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
-	struct drm_dp_mst_atomic_payload *new_payload =
-		drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	bool last_mst_stream;
 
@@ -604,8 +596,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 
 	wait_for_act_sent(encoder, old_crtc_state);
 
-	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state,
-				    old_payload, new_payload);
+	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, &state->base, connector->port);
 
 	intel_ddi_disable_transcoder_func(old_crtc_state);
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index bba01fa0780c9..1ed724fe11f96 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -889,17 +889,13 @@ nv50_msto_cleanup(struct drm_atomic_state *state,
 	struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
 	struct drm_dp_mst_atomic_payload *new_payload =
 		drm_atomic_get_mst_payload_state(new_mst_state, msto->mstc->port);
-	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(state, mgr);
-	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, msto->mstc->port);
 
 	NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
 
 	if (msto->disabled) {
 		msto->mstc = NULL;
 		msto->disabled = false;
-		drm_dp_remove_payload_part2(mgr, new_mst_state, old_payload, new_payload);
+		drm_dp_remove_payload_part2(mgr, state, msto->mstc->port);
 	} else if (msto->enabled) {
 		drm_dp_add_payload_part2(mgr, state, new_payload);
 		msto->enabled = false;
diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
index 4429d3b1745b6..9288501ffe8d2 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -856,9 +856,11 @@ void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_dp_mst_topology_state *mst_state,
 				 struct drm_dp_mst_atomic_payload *payload);
 void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
-				 struct drm_dp_mst_topology_state *mst_state,
-				 const struct drm_dp_mst_atomic_payload *old_payload,
-				 struct drm_dp_mst_atomic_payload *new_payload);
+				 struct drm_atomic_state *state,
+				 struct drm_dp_mst_port *port);
+int drm_dp_remove_current_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
+					struct drm_atomic_state *state,
+					struct drm_dp_mst_port *port);
 
 int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
 
> Thanks for helping me out here.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-09-12 11:18                         ` Imre Deak
  0 siblings, 0 replies; 38+ messages in thread
From: Imre Deak @ 2023-09-12 11:18 UTC (permalink / raw)
  To: Lin, Wayne
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

On Tue, Sep 12, 2023 at 07:26:29AM +0000, Lin, Wayne wrote:
> [Public]
> [...]
> >
> > I'd like to be sure that the payload is removed with the size it was added with
> > in the previous commit and as I wrote above not depend for this on the new
> > payload state with a mixture of old/current/new states.
> > Based on that I'd be ok for instance with a new
> >
> > int drm_dp_remove_port_payload(mgr, mst_state, port)
> >
> > function which looks up / removes the payload with the time_slots calculated
> > based on the payload table as in your patch and returns the calculated
> > time_slots.
> >
> > The AMD driver could call the above function and the current
> > drm_dp_remove_payload(mgr, mst_state, old_payload) function would be
> >
> >       time_slots = drm_dp_remove_port_payload(mgr, mst_state,
> > old_payload->port);
> >       WARN_ON(time_slots != old_payload->time_slots);
> >
> > --Imre
> 
> Sorry but I might not fully understand what you suggested here. Would like to know
> if you agree on referring to the time slot number of the payload table at the moment
> is better then referring old_payload->time_slots for drm_dp_remove_payload()? If
> you agree on that, my patch actually is just replacing old_payload->time_slots with
> the more appropriate one. Not adding mixture of old/current but replacing the old
> with the current one. 

The new_payload state contains a mixture of old/current/new state at the
moment and this patch adds more dependency on that, recalculating the
old payload size from that state. For i915 this recalculation isn't
needed, the size is already available in the old payload state.

> And like what I explained in previous example, when calling
> drm_dp_remove_payload(), the time slot number to be removed shouldn't be
> constrained to the one in previous commit. The number in the payload table when
> we're about to remove the payload might be a better choice. Could you elaborate
> more what's the mixture that this patch is adding on, please?
>
> As for the changing suggestion, are you suggesting to create a new function
> drm_dp_remove_port_payload() to wrap up the calculation in my patch? If so, I think
> that's the consensus to use current time slot number to replace the one in old_payload.
> Therefore, it doesn't have to pass old_payload to drm_dp_remove_port_payload(), and
> "WARN_ON(time_slots != old_payload->time_slots);" is not appropriate as for the
> example that I gave previously.

I meant something like the following:

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index cbef4ff28cd8a..0555433d8050b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -343,7 +343,7 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_dp_mst_topology_state *mst_state;
 	struct drm_dp_mst_topology_mgr *mst_mgr;
-	struct drm_dp_mst_atomic_payload *new_payload, *old_payload;
+	struct drm_dp_mst_atomic_payload *new_payload;
 	enum mst_progress_status set_flag = MST_ALLOCATE_NEW_PAYLOAD;
 	enum mst_progress_status clr_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
 	int ret = 0;
@@ -366,9 +366,8 @@ bool dm_helpers_dp_mst_send_payload_allocation(
 	if (enable) {
 		ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload);
 	} else {
-		dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
-						 new_payload, old_payload);
-		drm_dp_remove_payload_part2(mst_mgr, mst_state, old_payload, new_payload);
+		drm_dp_remove_current_payload_part2(mst_mgr, mst_state->base.state,
+						    aconnector->mst_output_port);
 	}
 
 	if (ret) {
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index e04f87ff755ac..4d25dba789e91 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3382,37 +3382,70 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part1);
  * drm_dp_remove_payload_part2() - Remove an MST payload locally
  * @mgr: Manager to use.
  * @mst_state: The MST atomic state
- * @old_payload: The payload with its old state
- * @new_payload: The payload with its latest state
+ * @port: MST port
  *
  * Updates the starting time slots of all other payloads which would have been shifted towards
  * the start of the payload ID table as a result of removing a payload. Driver should call this
  * function whenever it removes a payload in its HW. It's independent to the result of payload
  * allocation/deallocation at branch devices along the virtual channel.
  */
-void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
-				 struct drm_dp_mst_topology_state *mst_state,
-				 const struct drm_dp_mst_atomic_payload *old_payload,
-				 struct drm_dp_mst_atomic_payload *new_payload)
+int drm_dp_remove_current_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
+					struct drm_atomic_state *state,
+					struct drm_dp_mst_port *port)
 {
 	struct drm_dp_mst_atomic_payload *pos;
+	struct drm_dp_mst_topology_state *mst_state =
+		drm_atomic_get_new_mst_topology_state(state, mgr);
+	struct drm_dp_mst_atomic_payload *new_payload =
+		drm_atomic_get_mst_payload_state(mst_state, port);
+	int time_slots_to_remove;
+	u8 next_payload_vc_start = mgr->next_start_slot;
+
+	/* Find the current allocated time slot number of the payload */
+	list_for_each_entry(pos, &mst_state->payloads, next) {
+		if (pos != new_payload &&
+		    pos->vc_start_slot > new_payload->vc_start_slot &&
+		    pos->vc_start_slot < next_payload_vc_start)
+			next_payload_vc_start = pos->vc_start_slot;
+	}
+
+	time_slots_to_remove = next_payload_vc_start - new_payload->vc_start_slot;
 
 	/* Remove local payload allocation */
 	list_for_each_entry(pos, &mst_state->payloads, next) {
 		if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)
-			pos->vc_start_slot -= old_payload->time_slots;
+			pos->vc_start_slot -= time_slots_to_remove;
 	}
 	new_payload->vc_start_slot = -1;
 
 	mgr->payload_count--;
-	mgr->next_start_slot -= old_payload->time_slots;
+	mgr->next_start_slot -= time_slots_to_remove;
 
 	if (new_payload->delete)
 		drm_dp_mst_put_port_malloc(new_payload->port);
 
 	new_payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
+
+	return time_slots_to_remove;
+}
+EXPORT_SYMBOL(drm_dp_remove_current_payload_part2);
+
+void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
+				 struct drm_atomic_state *state,
+				 struct drm_dp_mst_port *port)
+{
+	struct drm_dp_mst_topology_state *old_mst_state =
+		drm_atomic_get_old_mst_topology_state(state, mgr);
+	struct drm_dp_mst_atomic_payload *old_payload =
+		drm_atomic_get_mst_payload_state(old_mst_state, port);
+	int time_slots;
+
+	time_slots = drm_dp_remove_current_payload_part2(mgr, state, port);
+
+	drm_WARN_ON(mgr->dev, time_slots != old_payload->time_slots);
 }
 EXPORT_SYMBOL(drm_dp_remove_payload_part2);
+
 /**
  * drm_dp_add_payload_part2() - Execute payload update part 2
  * @mgr: Manager to use.
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 1c7f0b6afe475..3ab491d9c8d27 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -576,14 +576,6 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 	struct intel_dp *intel_dp = &dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
-	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
-	struct drm_dp_mst_topology_state *new_mst_state =
-		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
-	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
-	struct drm_dp_mst_atomic_payload *new_payload =
-		drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	bool last_mst_stream;
 
@@ -604,8 +596,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 
 	wait_for_act_sent(encoder, old_crtc_state);
 
-	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state,
-				    old_payload, new_payload);
+	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, &state->base, connector->port);
 
 	intel_ddi_disable_transcoder_func(old_crtc_state);
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index bba01fa0780c9..1ed724fe11f96 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -889,17 +889,13 @@ nv50_msto_cleanup(struct drm_atomic_state *state,
 	struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
 	struct drm_dp_mst_atomic_payload *new_payload =
 		drm_atomic_get_mst_payload_state(new_mst_state, msto->mstc->port);
-	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(state, mgr);
-	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, msto->mstc->port);
 
 	NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
 
 	if (msto->disabled) {
 		msto->mstc = NULL;
 		msto->disabled = false;
-		drm_dp_remove_payload_part2(mgr, new_mst_state, old_payload, new_payload);
+		drm_dp_remove_payload_part2(mgr, state, msto->mstc->port);
 	} else if (msto->enabled) {
 		drm_dp_add_payload_part2(mgr, state, new_payload);
 		msto->enabled = false;
diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
index 4429d3b1745b6..9288501ffe8d2 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -856,9 +856,11 @@ void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_dp_mst_topology_state *mst_state,
 				 struct drm_dp_mst_atomic_payload *payload);
 void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
-				 struct drm_dp_mst_topology_state *mst_state,
-				 const struct drm_dp_mst_atomic_payload *old_payload,
-				 struct drm_dp_mst_atomic_payload *new_payload);
+				 struct drm_atomic_state *state,
+				 struct drm_dp_mst_port *port);
+int drm_dp_remove_current_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
+					struct drm_atomic_state *state,
+					struct drm_dp_mst_port *port);
 
 int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
 
> Thanks for helping me out here.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
  2023-09-12 11:18                         ` Imre Deak
@ 2023-09-14  3:29                           ` Lin, Wayne
  -1 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-09-14  3:29 UTC (permalink / raw)
  To: imre.deak; +Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel

[Public]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Tuesday, September 12, 2023 7:19 PM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Tue, Sep 12, 2023 at 07:26:29AM +0000, Lin, Wayne wrote:
> > [Public]
> > [...]
> > >
> > > I'd like to be sure that the payload is removed with the size it was
> > > added with in the previous commit and as I wrote above not depend
> > > for this on the new payload state with a mixture of old/current/new states.
> > > Based on that I'd be ok for instance with a new
> > >
> > > int drm_dp_remove_port_payload(mgr, mst_state, port)
> > >
> > > function which looks up / removes the payload with the time_slots
> > > calculated based on the payload table as in your patch and returns
> > > the calculated time_slots.
> > >
> > > The AMD driver could call the above function and the current
> > > drm_dp_remove_payload(mgr, mst_state, old_payload) function would be
> > >
> > >       time_slots = drm_dp_remove_port_payload(mgr, mst_state,
> > > old_payload->port);
> > >       WARN_ON(time_slots != old_payload->time_slots);
> > >
> > > --Imre
> >
> > Sorry but I might not fully understand what you suggested here. Would
> > like to know if you agree on referring to the time slot number of the
> > payload table at the moment is better then referring
> > old_payload->time_slots for drm_dp_remove_payload()? If you agree on
> > that, my patch actually is just replacing old_payload->time_slots with
> > the more appropriate one. Not adding mixture of old/current but replacing
> the old with the current one.
>
> The new_payload state contains a mixture of old/current/new state at the
> moment and this patch adds more dependency on that, recalculating the old
> payload size from that state. For i915 this recalculation isn't needed, the size is
> already available in the old payload state.
>

I see. Thanks, Imre. So it's about the idea to have another patch to extract things
like vc_start_slot out of mst state.

> > And like what I explained in previous example, when calling
> > drm_dp_remove_payload(), the time slot number to be removed shouldn't
> > be constrained to the one in previous commit. The number in the
> > payload table when we're about to remove the payload might be a better
> > choice. Could you elaborate more what's the mixture that this patch is
> adding on, please?
> >
> > As for the changing suggestion, are you suggesting to create a new
> > function
> > drm_dp_remove_port_payload() to wrap up the calculation in my patch?
> > If so, I think that's the consensus to use current time slot number to replace
> the one in old_payload.
> > Therefore, it doesn't have to pass old_payload to
> > drm_dp_remove_port_payload(), and "WARN_ON(time_slots !=
> > old_payload->time_slots);" is not appropriate as for the example that I gave
> previously.
>
> I meant something like the following:

The change looks good to me. I'll update the patch. Thanks for the help.

>
> diff --git
> a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index cbef4ff28cd8a..0555433d8050b 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -343,7 +343,7 @@ bool dm_helpers_dp_mst_send_payload_allocation(
>       struct amdgpu_dm_connector *aconnector;
>       struct drm_dp_mst_topology_state *mst_state;
>       struct drm_dp_mst_topology_mgr *mst_mgr;
> -     struct drm_dp_mst_atomic_payload *new_payload, *old_payload;
> +     struct drm_dp_mst_atomic_payload *new_payload;
>       enum mst_progress_status set_flag =
> MST_ALLOCATE_NEW_PAYLOAD;
>       enum mst_progress_status clr_flag =
> MST_CLEAR_ALLOCATED_PAYLOAD;
>       int ret = 0;
> @@ -366,9 +366,8 @@ bool dm_helpers_dp_mst_send_payload_allocation(
>       if (enable) {
>               ret = drm_dp_add_payload_part2(mst_mgr, mst_state-
> >base.state, new_payload);
>       } else {
> -             dm_helpers_construct_old_payload(stream->link, mst_state-
> >pbn_div,
> -                                              new_payload, old_payload);
> -             drm_dp_remove_payload_part2(mst_mgr, mst_state,
> old_payload, new_payload);
> +             drm_dp_remove_current_payload_part2(mst_mgr,
> mst_state->base.state,
> +                                                 aconnector-
> >mst_output_port);
>       }
>
>       if (ret) {
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index e04f87ff755ac..4d25dba789e91 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -3382,37 +3382,70 @@
> EXPORT_SYMBOL(drm_dp_remove_payload_part1);
>   * drm_dp_remove_payload_part2() - Remove an MST payload locally
>   * @mgr: Manager to use.
>   * @mst_state: The MST atomic state
> - * @old_payload: The payload with its old state
> - * @new_payload: The payload with its latest state
> + * @port: MST port
>   *
>   * Updates the starting time slots of all other payloads which would have been
> shifted towards
>   * the start of the payload ID table as a result of removing a payload. Driver
> should call this
>   * function whenever it removes a payload in its HW. It's independent to the
> result of payload
>   * allocation/deallocation at branch devices along the virtual channel.
>   */
> -void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr
> *mgr,
> -                              struct drm_dp_mst_topology_state
> *mst_state,
> -                              const struct drm_dp_mst_atomic_payload
> *old_payload,
> -                              struct drm_dp_mst_atomic_payload
> *new_payload)
> +int drm_dp_remove_current_payload_part2(struct
> drm_dp_mst_topology_mgr *mgr,
> +                                     struct drm_atomic_state *state,
> +                                     struct drm_dp_mst_port *port)
>  {
>       struct drm_dp_mst_atomic_payload *pos;
> +     struct drm_dp_mst_topology_state *mst_state =
> +             drm_atomic_get_new_mst_topology_state(state, mgr);
> +     struct drm_dp_mst_atomic_payload *new_payload =
> +             drm_atomic_get_mst_payload_state(mst_state, port);
> +     int time_slots_to_remove;
> +     u8 next_payload_vc_start = mgr->next_start_slot;
> +
> +     /* Find the current allocated time slot number of the payload */
> +     list_for_each_entry(pos, &mst_state->payloads, next) {
> +             if (pos != new_payload &&
> +                 pos->vc_start_slot > new_payload->vc_start_slot &&
> +                 pos->vc_start_slot < next_payload_vc_start)
> +                     next_payload_vc_start = pos->vc_start_slot;
> +     }
> +
> +     time_slots_to_remove = next_payload_vc_start -
> +new_payload->vc_start_slot;
>
>       /* Remove local payload allocation */
>       list_for_each_entry(pos, &mst_state->payloads, next) {
>               if (pos != new_payload && pos->vc_start_slot > new_payload-
> >vc_start_slot)
> -                     pos->vc_start_slot -= old_payload->time_slots;
> +                     pos->vc_start_slot -= time_slots_to_remove;
>       }
>       new_payload->vc_start_slot = -1;
>
>       mgr->payload_count--;
> -     mgr->next_start_slot -= old_payload->time_slots;
> +     mgr->next_start_slot -= time_slots_to_remove;
>
>       if (new_payload->delete)
>               drm_dp_mst_put_port_malloc(new_payload->port);
>
>       new_payload->payload_allocation_status =
> DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> +
> +     return time_slots_to_remove;
> +}
> +EXPORT_SYMBOL(drm_dp_remove_current_payload_part2);
> +
> +void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr
> *mgr,
> +                              struct drm_atomic_state *state,
> +                              struct drm_dp_mst_port *port)
> +{
> +     struct drm_dp_mst_topology_state *old_mst_state =
> +             drm_atomic_get_old_mst_topology_state(state, mgr);
> +     struct drm_dp_mst_atomic_payload *old_payload =
> +             drm_atomic_get_mst_payload_state(old_mst_state, port);
> +     int time_slots;
> +
> +     time_slots = drm_dp_remove_current_payload_part2(mgr, state,
> port);
> +
> +     drm_WARN_ON(mgr->dev, time_slots != old_payload->time_slots);
>  }
>  EXPORT_SYMBOL(drm_dp_remove_payload_part2);
> +
>  /**
>   * drm_dp_add_payload_part2() - Execute payload update part 2
>   * @mgr: Manager to use.
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 1c7f0b6afe475..3ab491d9c8d27 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -576,14 +576,6 @@ static void intel_mst_post_disable_dp(struct
> intel_atomic_state *state,
>       struct intel_dp *intel_dp = &dig_port->dp;
>       struct intel_connector *connector =
>               to_intel_connector(old_conn_state->connector);
> -     struct drm_dp_mst_topology_state *old_mst_state =
> -             drm_atomic_get_old_mst_topology_state(&state->base,
> &intel_dp->mst_mgr);
> -     struct drm_dp_mst_topology_state *new_mst_state =
> -             drm_atomic_get_new_mst_topology_state(&state->base,
> &intel_dp->mst_mgr);
> -     const struct drm_dp_mst_atomic_payload *old_payload =
> -             drm_atomic_get_mst_payload_state(old_mst_state,
> connector->port);
> -     struct drm_dp_mst_atomic_payload *new_payload =
> -             drm_atomic_get_mst_payload_state(new_mst_state,
> connector->port);
>       struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>       bool last_mst_stream;
>
> @@ -604,8 +596,7 @@ static void intel_mst_post_disable_dp(struct
> intel_atomic_state *state,
>
>       wait_for_act_sent(encoder, old_crtc_state);
>
> -     drm_dp_remove_payload_part2(&intel_dp->mst_mgr,
> new_mst_state,
> -                                 old_payload, new_payload);
> +     drm_dp_remove_payload_part2(&intel_dp->mst_mgr, &state->base,
> +connector->port);
>
>       intel_ddi_disable_transcoder_func(old_crtc_state);
>
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index bba01fa0780c9..1ed724fe11f96 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> @@ -889,17 +889,13 @@ nv50_msto_cleanup(struct drm_atomic_state
> *state,
>       struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
>       struct drm_dp_mst_atomic_payload *new_payload =
>               drm_atomic_get_mst_payload_state(new_mst_state, msto-
> >mstc->port);
> -     struct drm_dp_mst_topology_state *old_mst_state =
> -             drm_atomic_get_old_mst_topology_state(state, mgr);
> -     const struct drm_dp_mst_atomic_payload *old_payload =
> -             drm_atomic_get_mst_payload_state(old_mst_state, msto-
> >mstc->port);
>
>       NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
>
>       if (msto->disabled) {
>               msto->mstc = NULL;
>               msto->disabled = false;
> -             drm_dp_remove_payload_part2(mgr, new_mst_state,
> old_payload, new_payload);
> +             drm_dp_remove_payload_part2(mgr, state, msto->mstc-
> >port);
>       } else if (msto->enabled) {
>               drm_dp_add_payload_part2(mgr, state, new_payload);
>               msto->enabled = false;
> diff --git a/include/drm/display/drm_dp_mst_helper.h
> b/include/drm/display/drm_dp_mst_helper.h
> index 4429d3b1745b6..9288501ffe8d2 100644
> --- a/include/drm/display/drm_dp_mst_helper.h
> +++ b/include/drm/display/drm_dp_mst_helper.h
> @@ -856,9 +856,11 @@ void drm_dp_remove_payload_part1(struct
> drm_dp_mst_topology_mgr *mgr,
>                                struct drm_dp_mst_topology_state
> *mst_state,
>                                struct drm_dp_mst_atomic_payload
> *payload);  void drm_dp_remove_payload_part2(struct
> drm_dp_mst_topology_mgr *mgr,
> -                              struct drm_dp_mst_topology_state
> *mst_state,
> -                              const struct drm_dp_mst_atomic_payload
> *old_payload,
> -                              struct drm_dp_mst_atomic_payload
> *new_payload);
> +                              struct drm_atomic_state *state,
> +                              struct drm_dp_mst_port *port);
> +int drm_dp_remove_current_payload_part2(struct
> drm_dp_mst_topology_mgr *mgr,
> +                                     struct drm_atomic_state *state,
> +                                     struct drm_dp_mst_port *port);
>
>  int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
>
> > Thanks for helping me out here.
--
Regards,
Wayne


^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
@ 2023-09-14  3:29                           ` Lin, Wayne
  0 siblings, 0 replies; 38+ messages in thread
From: Lin, Wayne @ 2023-09-14  3:29 UTC (permalink / raw)
  To: imre.deak
  Cc: jani.nikula, amd-gfx, Zuo, Jerry, dri-devel, Wentland, Harry,
	ville.syrjala

[Public]

> -----Original Message-----
> From: Imre Deak <imre.deak@intel.com>
> Sent: Tuesday, September 12, 2023 7:19 PM
> To: Lin, Wayne <Wayne.Lin@amd.com>
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> lyude@redhat.com; jani.nikula@intel.com; ville.syrjala@linux.intel.com;
> Wentland, Harry <Harry.Wentland@amd.com>; Zuo, Jerry
> <Jerry.Zuo@amd.com>
> Subject: Re: [PATCH 3/3] drm/mst: adjust the function
> drm_dp_remove_payload_part2()
>
> On Tue, Sep 12, 2023 at 07:26:29AM +0000, Lin, Wayne wrote:
> > [Public]
> > [...]
> > >
> > > I'd like to be sure that the payload is removed with the size it was
> > > added with in the previous commit and as I wrote above not depend
> > > for this on the new payload state with a mixture of old/current/new states.
> > > Based on that I'd be ok for instance with a new
> > >
> > > int drm_dp_remove_port_payload(mgr, mst_state, port)
> > >
> > > function which looks up / removes the payload with the time_slots
> > > calculated based on the payload table as in your patch and returns
> > > the calculated time_slots.
> > >
> > > The AMD driver could call the above function and the current
> > > drm_dp_remove_payload(mgr, mst_state, old_payload) function would be
> > >
> > >       time_slots = drm_dp_remove_port_payload(mgr, mst_state,
> > > old_payload->port);
> > >       WARN_ON(time_slots != old_payload->time_slots);
> > >
> > > --Imre
> >
> > Sorry but I might not fully understand what you suggested here. Would
> > like to know if you agree on referring to the time slot number of the
> > payload table at the moment is better then referring
> > old_payload->time_slots for drm_dp_remove_payload()? If you agree on
> > that, my patch actually is just replacing old_payload->time_slots with
> > the more appropriate one. Not adding mixture of old/current but replacing
> the old with the current one.
>
> The new_payload state contains a mixture of old/current/new state at the
> moment and this patch adds more dependency on that, recalculating the old
> payload size from that state. For i915 this recalculation isn't needed, the size is
> already available in the old payload state.
>

I see. Thanks, Imre. So it's about the idea to have another patch to extract things
like vc_start_slot out of mst state.

> > And like what I explained in previous example, when calling
> > drm_dp_remove_payload(), the time slot number to be removed shouldn't
> > be constrained to the one in previous commit. The number in the
> > payload table when we're about to remove the payload might be a better
> > choice. Could you elaborate more what's the mixture that this patch is
> adding on, please?
> >
> > As for the changing suggestion, are you suggesting to create a new
> > function
> > drm_dp_remove_port_payload() to wrap up the calculation in my patch?
> > If so, I think that's the consensus to use current time slot number to replace
> the one in old_payload.
> > Therefore, it doesn't have to pass old_payload to
> > drm_dp_remove_port_payload(), and "WARN_ON(time_slots !=
> > old_payload->time_slots);" is not appropriate as for the example that I gave
> previously.
>
> I meant something like the following:

The change looks good to me. I'll update the patch. Thanks for the help.

>
> diff --git
> a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index cbef4ff28cd8a..0555433d8050b 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -343,7 +343,7 @@ bool dm_helpers_dp_mst_send_payload_allocation(
>       struct amdgpu_dm_connector *aconnector;
>       struct drm_dp_mst_topology_state *mst_state;
>       struct drm_dp_mst_topology_mgr *mst_mgr;
> -     struct drm_dp_mst_atomic_payload *new_payload, *old_payload;
> +     struct drm_dp_mst_atomic_payload *new_payload;
>       enum mst_progress_status set_flag =
> MST_ALLOCATE_NEW_PAYLOAD;
>       enum mst_progress_status clr_flag =
> MST_CLEAR_ALLOCATED_PAYLOAD;
>       int ret = 0;
> @@ -366,9 +366,8 @@ bool dm_helpers_dp_mst_send_payload_allocation(
>       if (enable) {
>               ret = drm_dp_add_payload_part2(mst_mgr, mst_state-
> >base.state, new_payload);
>       } else {
> -             dm_helpers_construct_old_payload(stream->link, mst_state-
> >pbn_div,
> -                                              new_payload, old_payload);
> -             drm_dp_remove_payload_part2(mst_mgr, mst_state,
> old_payload, new_payload);
> +             drm_dp_remove_current_payload_part2(mst_mgr,
> mst_state->base.state,
> +                                                 aconnector-
> >mst_output_port);
>       }
>
>       if (ret) {
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index e04f87ff755ac..4d25dba789e91 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -3382,37 +3382,70 @@
> EXPORT_SYMBOL(drm_dp_remove_payload_part1);
>   * drm_dp_remove_payload_part2() - Remove an MST payload locally
>   * @mgr: Manager to use.
>   * @mst_state: The MST atomic state
> - * @old_payload: The payload with its old state
> - * @new_payload: The payload with its latest state
> + * @port: MST port
>   *
>   * Updates the starting time slots of all other payloads which would have been
> shifted towards
>   * the start of the payload ID table as a result of removing a payload. Driver
> should call this
>   * function whenever it removes a payload in its HW. It's independent to the
> result of payload
>   * allocation/deallocation at branch devices along the virtual channel.
>   */
> -void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr
> *mgr,
> -                              struct drm_dp_mst_topology_state
> *mst_state,
> -                              const struct drm_dp_mst_atomic_payload
> *old_payload,
> -                              struct drm_dp_mst_atomic_payload
> *new_payload)
> +int drm_dp_remove_current_payload_part2(struct
> drm_dp_mst_topology_mgr *mgr,
> +                                     struct drm_atomic_state *state,
> +                                     struct drm_dp_mst_port *port)
>  {
>       struct drm_dp_mst_atomic_payload *pos;
> +     struct drm_dp_mst_topology_state *mst_state =
> +             drm_atomic_get_new_mst_topology_state(state, mgr);
> +     struct drm_dp_mst_atomic_payload *new_payload =
> +             drm_atomic_get_mst_payload_state(mst_state, port);
> +     int time_slots_to_remove;
> +     u8 next_payload_vc_start = mgr->next_start_slot;
> +
> +     /* Find the current allocated time slot number of the payload */
> +     list_for_each_entry(pos, &mst_state->payloads, next) {
> +             if (pos != new_payload &&
> +                 pos->vc_start_slot > new_payload->vc_start_slot &&
> +                 pos->vc_start_slot < next_payload_vc_start)
> +                     next_payload_vc_start = pos->vc_start_slot;
> +     }
> +
> +     time_slots_to_remove = next_payload_vc_start -
> +new_payload->vc_start_slot;
>
>       /* Remove local payload allocation */
>       list_for_each_entry(pos, &mst_state->payloads, next) {
>               if (pos != new_payload && pos->vc_start_slot > new_payload-
> >vc_start_slot)
> -                     pos->vc_start_slot -= old_payload->time_slots;
> +                     pos->vc_start_slot -= time_slots_to_remove;
>       }
>       new_payload->vc_start_slot = -1;
>
>       mgr->payload_count--;
> -     mgr->next_start_slot -= old_payload->time_slots;
> +     mgr->next_start_slot -= time_slots_to_remove;
>
>       if (new_payload->delete)
>               drm_dp_mst_put_port_malloc(new_payload->port);
>
>       new_payload->payload_allocation_status =
> DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> +
> +     return time_slots_to_remove;
> +}
> +EXPORT_SYMBOL(drm_dp_remove_current_payload_part2);
> +
> +void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr
> *mgr,
> +                              struct drm_atomic_state *state,
> +                              struct drm_dp_mst_port *port)
> +{
> +     struct drm_dp_mst_topology_state *old_mst_state =
> +             drm_atomic_get_old_mst_topology_state(state, mgr);
> +     struct drm_dp_mst_atomic_payload *old_payload =
> +             drm_atomic_get_mst_payload_state(old_mst_state, port);
> +     int time_slots;
> +
> +     time_slots = drm_dp_remove_current_payload_part2(mgr, state,
> port);
> +
> +     drm_WARN_ON(mgr->dev, time_slots != old_payload->time_slots);
>  }
>  EXPORT_SYMBOL(drm_dp_remove_payload_part2);
> +
>  /**
>   * drm_dp_add_payload_part2() - Execute payload update part 2
>   * @mgr: Manager to use.
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 1c7f0b6afe475..3ab491d9c8d27 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -576,14 +576,6 @@ static void intel_mst_post_disable_dp(struct
> intel_atomic_state *state,
>       struct intel_dp *intel_dp = &dig_port->dp;
>       struct intel_connector *connector =
>               to_intel_connector(old_conn_state->connector);
> -     struct drm_dp_mst_topology_state *old_mst_state =
> -             drm_atomic_get_old_mst_topology_state(&state->base,
> &intel_dp->mst_mgr);
> -     struct drm_dp_mst_topology_state *new_mst_state =
> -             drm_atomic_get_new_mst_topology_state(&state->base,
> &intel_dp->mst_mgr);
> -     const struct drm_dp_mst_atomic_payload *old_payload =
> -             drm_atomic_get_mst_payload_state(old_mst_state,
> connector->port);
> -     struct drm_dp_mst_atomic_payload *new_payload =
> -             drm_atomic_get_mst_payload_state(new_mst_state,
> connector->port);
>       struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>       bool last_mst_stream;
>
> @@ -604,8 +596,7 @@ static void intel_mst_post_disable_dp(struct
> intel_atomic_state *state,
>
>       wait_for_act_sent(encoder, old_crtc_state);
>
> -     drm_dp_remove_payload_part2(&intel_dp->mst_mgr,
> new_mst_state,
> -                                 old_payload, new_payload);
> +     drm_dp_remove_payload_part2(&intel_dp->mst_mgr, &state->base,
> +connector->port);
>
>       intel_ddi_disable_transcoder_func(old_crtc_state);
>
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index bba01fa0780c9..1ed724fe11f96 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> @@ -889,17 +889,13 @@ nv50_msto_cleanup(struct drm_atomic_state
> *state,
>       struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev);
>       struct drm_dp_mst_atomic_payload *new_payload =
>               drm_atomic_get_mst_payload_state(new_mst_state, msto-
> >mstc->port);
> -     struct drm_dp_mst_topology_state *old_mst_state =
> -             drm_atomic_get_old_mst_topology_state(state, mgr);
> -     const struct drm_dp_mst_atomic_payload *old_payload =
> -             drm_atomic_get_mst_payload_state(old_mst_state, msto-
> >mstc->port);
>
>       NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
>
>       if (msto->disabled) {
>               msto->mstc = NULL;
>               msto->disabled = false;
> -             drm_dp_remove_payload_part2(mgr, new_mst_state,
> old_payload, new_payload);
> +             drm_dp_remove_payload_part2(mgr, state, msto->mstc-
> >port);
>       } else if (msto->enabled) {
>               drm_dp_add_payload_part2(mgr, state, new_payload);
>               msto->enabled = false;
> diff --git a/include/drm/display/drm_dp_mst_helper.h
> b/include/drm/display/drm_dp_mst_helper.h
> index 4429d3b1745b6..9288501ffe8d2 100644
> --- a/include/drm/display/drm_dp_mst_helper.h
> +++ b/include/drm/display/drm_dp_mst_helper.h
> @@ -856,9 +856,11 @@ void drm_dp_remove_payload_part1(struct
> drm_dp_mst_topology_mgr *mgr,
>                                struct drm_dp_mst_topology_state
> *mst_state,
>                                struct drm_dp_mst_atomic_payload
> *payload);  void drm_dp_remove_payload_part2(struct
> drm_dp_mst_topology_mgr *mgr,
> -                              struct drm_dp_mst_topology_state
> *mst_state,
> -                              const struct drm_dp_mst_atomic_payload
> *old_payload,
> -                              struct drm_dp_mst_atomic_payload
> *new_payload);
> +                              struct drm_atomic_state *state,
> +                              struct drm_dp_mst_port *port);
> +int drm_dp_remove_current_payload_part2(struct
> drm_dp_mst_topology_mgr *mgr,
> +                                     struct drm_atomic_state *state,
> +                                     struct drm_dp_mst_port *port);
>
>  int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
>
> > Thanks for helping me out here.
--
Regards,
Wayne


^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2023-09-14  3:29 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-04  6:20 [PATCH 0/3] Refactor and clean up codes of mst Wayne Lin
2023-08-04  6:20 ` Wayne Lin
2023-08-04  6:20 ` [PATCH 1/3] drm/mst: delete unnecessary case in drm_dp_add_payload_part2() Wayne Lin
2023-08-04  6:20   ` Wayne Lin
2023-08-04  6:20 ` [PATCH 2/3] drm/mst: Refactor the flow for payload allocation/removement Wayne Lin
2023-08-04  6:20   ` Wayne Lin
2023-08-04  9:19   ` kernel test robot
2023-08-04  9:19     ` kernel test robot
2023-08-04 14:47   ` kernel test robot
2023-08-04 14:47     ` kernel test robot
2023-08-04  6:20 ` [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2() Wayne Lin
2023-08-04  6:20   ` Wayne Lin
2023-08-04 15:31   ` Imre Deak
2023-08-04 15:31     ` Imre Deak
2023-08-07  2:43     ` Lin, Wayne
2023-08-07  2:43       ` Lin, Wayne
2023-08-07 15:59       ` Imre Deak
2023-08-07 15:59         ` Imre Deak
2023-08-08  3:47         ` Lin, Wayne
2023-08-08  3:47           ` Lin, Wayne
2023-08-18 17:46           ` Imre Deak
2023-08-18 17:46             ` Imre Deak
2023-08-23  3:16             ` Lin, Wayne
2023-08-23  3:16               ` Lin, Wayne
2023-08-25 13:55               ` Imre Deak
2023-08-25 13:55                 ` Imre Deak
2023-09-07  3:44                 ` Lin, Wayne
2023-09-07  3:44                   ` Lin, Wayne
2023-09-08 19:18                   ` Imre Deak
2023-09-08 19:18                     ` Imre Deak
2023-09-12  7:26                     ` Lin, Wayne
2023-09-12  7:26                       ` Lin, Wayne
2023-09-12 11:18                       ` Imre Deak
2023-09-12 11:18                         ` Imre Deak
2023-09-14  3:29                         ` Lin, Wayne
2023-09-14  3:29                           ` Lin, Wayne
2023-08-17 21:38         ` Lyude Paul
2023-08-17 21:38           ` Lyude Paul

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.