From: Jani Nikula <jani.nikula@intel.com>
To: Lyude Paul <lyude@redhat.com>,
dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org,
amd-gfx@lists.freedesktop.org
Cc: "Thomas Zimmermann" <tzimmermann@suse.de>,
"David Airlie" <airlied@linux.ie>,
"Daniel Vetter" <daniel.vetter@ffwll.ch>,
"Imre Deak" <imre.deak@intel.com>,
"open list" <linux-kernel@vger.kernel.org>,
"Bhawanpreet Lakha" <Bhawanpreet.Lakha@amd.com>,
"Fangzhi Zuo" <Jerry.Zuo@amd.com>,
"Daniel Vetter" <daniel@ffwll.ch>,
"Wayne Lin" <Wayne.Lin@amd.com>, "Sean Paul" <sean@poorly.run>,
"Ville Syrjälä" <ville.syrjala@linux.intel.com>
Subject: Re: [RESEND RFC 07/18] drm/display/dp_mst: Add helper for finding payloads in atomic MST state
Date: Wed, 29 Jun 2022 16:22:07 +0300 [thread overview]
Message-ID: <87v8sjppts.fsf@intel.com> (raw)
In-Reply-To: <20220607192933.1333228-8-lyude@redhat.com>
On Tue, 07 Jun 2022, Lyude Paul <lyude@redhat.com> wrote:
> We already open-code this quite often, and will be iterating through
> payloads even more once we've moved all of the payload tracking into the
> atomic state. So, let's add a helper for doing this.
>
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> Cc: Wayne Lin <Wayne.Lin@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Fangzhi Zuo <Jerry.Zuo@amd.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Sean Paul <sean@poorly.run>
> ---
> drivers/gpu/drm/display/drm_dp_mst_topology.c | 109 ++++++++----------
> 1 file changed, 45 insertions(+), 64 deletions(-)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index ec52f91b1f0e..0bc2c7a90c37 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -1737,6 +1737,19 @@ drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port) {}
> #define save_port_topology_ref(port, type)
> #endif
>
> +static struct drm_dp_mst_atomic_payload *
> +drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state,
> + struct drm_dp_mst_port *port)
> +{
> + struct drm_dp_mst_atomic_payload *payload;
> +
> + list_for_each_entry(payload, &state->payloads, next)
> + if (payload->port == port)
> + return payload;
> +
> + return NULL;
> +}
> +
> static void drm_dp_destroy_mst_branch_device(struct kref *kref)
> {
> struct drm_dp_mst_branch *mstb =
> @@ -4381,39 +4394,31 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state,
> int pbn_div)
> {
> struct drm_dp_mst_topology_state *topology_state;
> - struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
> - int prev_slots, prev_bw, req_slots;
> + struct drm_dp_mst_atomic_payload *payload = NULL;
> + int prev_slots = 0, prev_bw = 0, req_slots;
>
> topology_state = drm_atomic_get_mst_topology_state(state, mgr);
> if (IS_ERR(topology_state))
> return PTR_ERR(topology_state);
>
> /* Find the current allocation for this port, if any */
> - list_for_each_entry(pos, &topology_state->payloads, next) {
> - if (pos->port == port) {
> - payload = pos;
> - prev_slots = payload->time_slots;
> - prev_bw = payload->pbn;
> -
> - /*
> - * This should never happen, unless the driver tries
> - * releasing and allocating the same timeslot allocation,
> - * which is an error
> - */
> - if (WARN_ON(!prev_slots)) {
> - drm_err(mgr->dev,
> - "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",
> - port);
> - return -EINVAL;
> - }
> + payload = drm_atomic_get_mst_payload_state(topology_state, port);
> + if (payload) {
> + prev_slots = payload->time_slots;
> + prev_bw = payload->pbn;
>
> - break;
> + /*
> + * This should never happen, unless the driver tries
> + * releasing and allocating the same timeslot allocation,
> + * which is an error
> + */
> + if (WARN_ON(!prev_slots)) {
> + drm_err(mgr->dev,
> + "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",
> + port);
I guess I'd combine the WARN_ON() and drm_err() to a single
drm_WARN(). Having both is a silly. But can be a follow-up, not part of
this patch really.
> + return -EINVAL;
> }
> }
> - if (!payload) {
> - prev_slots = 0;
> - prev_bw = 0;
> - }
>
> if (pbn_div <= 0)
> pbn_div = mgr->pbn_div;
> @@ -4474,30 +4479,24 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,
> struct drm_dp_mst_port *port)
> {
> struct drm_dp_mst_topology_state *topology_state;
> - struct drm_dp_mst_atomic_payload *pos;
> - bool found = false;
> + struct drm_dp_mst_atomic_payload *payload;
>
> topology_state = drm_atomic_get_mst_topology_state(state, mgr);
> if (IS_ERR(topology_state))
> return PTR_ERR(topology_state);
>
> - list_for_each_entry(pos, &topology_state->payloads, next) {
> - if (pos->port == port) {
> - found = true;
> - break;
> - }
> - }
> - if (WARN_ON(!found)) {
> + payload = drm_atomic_get_mst_payload_state(topology_state, port);
> + if (WARN_ON(!payload)) {
> drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst state %p\n",
> port, &topology_state->base);
Ditto.
BR,
Jani.
> return -EINVAL;
> }
>
> - drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, pos->time_slots);
> - if (pos->time_slots) {
> + drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, payload->time_slots);
> + if (payload->time_slots) {
> drm_dp_mst_put_port_malloc(port);
> - pos->time_slots = 0;
> - pos->pbn = 0;
> + payload->time_slots = 0;
> + payload->pbn = 0;
> }
>
> return 0;
> @@ -5194,18 +5193,8 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
> return 0;
>
> if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
> - bool found = false;
> -
> - list_for_each_entry(payload, &state->payloads, next) {
> - if (payload->port != port)
> - continue;
> - if (!payload->pbn)
> - return 0;
> -
> - found = true;
> - break;
> - }
> - if (!found)
> + payload = drm_atomic_get_mst_payload_state(state, port);
> + if (!payload)
> return 0;
>
> /*
> @@ -5360,34 +5349,26 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
> bool enable)
> {
> struct drm_dp_mst_topology_state *mst_state;
> - struct drm_dp_mst_atomic_payload *pos;
> - bool found = false;
> + struct drm_dp_mst_atomic_payload *payload;
> int time_slots = 0;
>
> mst_state = drm_atomic_get_mst_topology_state(state, port->mgr);
> -
> if (IS_ERR(mst_state))
> return PTR_ERR(mst_state);
>
> - list_for_each_entry(pos, &mst_state->payloads, next) {
> - if (pos->port == port) {
> - found = true;
> - break;
> - }
> - }
> -
> - if (!found) {
> + payload = drm_atomic_get_mst_payload_state(mst_state, port);
> + if (!payload) {
> drm_dbg_atomic(state->dev,
> "[MST PORT:%p] Couldn't find payload in mst state %p\n",
> port, mst_state);
> return -EINVAL;
> }
>
> - if (pos->dsc_enabled == enable) {
> + if (payload->dsc_enabled == enable) {
> drm_dbg_atomic(state->dev,
> "[MST PORT:%p] DSC flag is already set to %d, returning %d time slots\n",
> - port, enable, pos->time_slots);
> - time_slots = pos->time_slots;
> + port, enable, payload->time_slots);
> + time_slots = payload->time_slots;
> }
>
> if (enable) {
> @@ -5399,7 +5380,7 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
> return -EINVAL;
> }
>
> - pos->dsc_enabled = enable;
> + payload->dsc_enabled = enable;
>
> return time_slots;
> }
--
Jani Nikula, Intel Open Source Graphics Center
WARNING: multiple messages have this Message-ID (diff)
From: Jani Nikula <jani.nikula@intel.com>
To: Lyude Paul <lyude@redhat.com>,
dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org,
amd-gfx@lists.freedesktop.org
Cc: "David Airlie" <airlied@linux.ie>,
"Imre Deak" <imre.deak@intel.com>,
"open list" <linux-kernel@vger.kernel.org>,
"Bhawanpreet Lakha" <Bhawanpreet.Lakha@amd.com>,
"Fangzhi Zuo" <Jerry.Zuo@amd.com>,
"Daniel Vetter" <daniel@ffwll.ch>,
"Wayne Lin" <Wayne.Lin@amd.com>, "Sean Paul" <sean@poorly.run>,
"Ville Syrjälä" <ville.syrjala@linux.intel.com>
Subject: Re: [Nouveau] [RESEND RFC 07/18] drm/display/dp_mst: Add helper for finding payloads in atomic MST state
Date: Wed, 29 Jun 2022 16:22:07 +0300 [thread overview]
Message-ID: <87v8sjppts.fsf@intel.com> (raw)
In-Reply-To: <20220607192933.1333228-8-lyude@redhat.com>
On Tue, 07 Jun 2022, Lyude Paul <lyude@redhat.com> wrote:
> We already open-code this quite often, and will be iterating through
> payloads even more once we've moved all of the payload tracking into the
> atomic state. So, let's add a helper for doing this.
>
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> Cc: Wayne Lin <Wayne.Lin@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Fangzhi Zuo <Jerry.Zuo@amd.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Sean Paul <sean@poorly.run>
> ---
> drivers/gpu/drm/display/drm_dp_mst_topology.c | 109 ++++++++----------
> 1 file changed, 45 insertions(+), 64 deletions(-)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index ec52f91b1f0e..0bc2c7a90c37 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -1737,6 +1737,19 @@ drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port) {}
> #define save_port_topology_ref(port, type)
> #endif
>
> +static struct drm_dp_mst_atomic_payload *
> +drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state,
> + struct drm_dp_mst_port *port)
> +{
> + struct drm_dp_mst_atomic_payload *payload;
> +
> + list_for_each_entry(payload, &state->payloads, next)
> + if (payload->port == port)
> + return payload;
> +
> + return NULL;
> +}
> +
> static void drm_dp_destroy_mst_branch_device(struct kref *kref)
> {
> struct drm_dp_mst_branch *mstb =
> @@ -4381,39 +4394,31 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state,
> int pbn_div)
> {
> struct drm_dp_mst_topology_state *topology_state;
> - struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
> - int prev_slots, prev_bw, req_slots;
> + struct drm_dp_mst_atomic_payload *payload = NULL;
> + int prev_slots = 0, prev_bw = 0, req_slots;
>
> topology_state = drm_atomic_get_mst_topology_state(state, mgr);
> if (IS_ERR(topology_state))
> return PTR_ERR(topology_state);
>
> /* Find the current allocation for this port, if any */
> - list_for_each_entry(pos, &topology_state->payloads, next) {
> - if (pos->port == port) {
> - payload = pos;
> - prev_slots = payload->time_slots;
> - prev_bw = payload->pbn;
> -
> - /*
> - * This should never happen, unless the driver tries
> - * releasing and allocating the same timeslot allocation,
> - * which is an error
> - */
> - if (WARN_ON(!prev_slots)) {
> - drm_err(mgr->dev,
> - "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",
> - port);
> - return -EINVAL;
> - }
> + payload = drm_atomic_get_mst_payload_state(topology_state, port);
> + if (payload) {
> + prev_slots = payload->time_slots;
> + prev_bw = payload->pbn;
>
> - break;
> + /*
> + * This should never happen, unless the driver tries
> + * releasing and allocating the same timeslot allocation,
> + * which is an error
> + */
> + if (WARN_ON(!prev_slots)) {
> + drm_err(mgr->dev,
> + "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",
> + port);
I guess I'd combine the WARN_ON() and drm_err() to a single
drm_WARN(). Having both is a silly. But can be a follow-up, not part of
this patch really.
> + return -EINVAL;
> }
> }
> - if (!payload) {
> - prev_slots = 0;
> - prev_bw = 0;
> - }
>
> if (pbn_div <= 0)
> pbn_div = mgr->pbn_div;
> @@ -4474,30 +4479,24 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,
> struct drm_dp_mst_port *port)
> {
> struct drm_dp_mst_topology_state *topology_state;
> - struct drm_dp_mst_atomic_payload *pos;
> - bool found = false;
> + struct drm_dp_mst_atomic_payload *payload;
>
> topology_state = drm_atomic_get_mst_topology_state(state, mgr);
> if (IS_ERR(topology_state))
> return PTR_ERR(topology_state);
>
> - list_for_each_entry(pos, &topology_state->payloads, next) {
> - if (pos->port == port) {
> - found = true;
> - break;
> - }
> - }
> - if (WARN_ON(!found)) {
> + payload = drm_atomic_get_mst_payload_state(topology_state, port);
> + if (WARN_ON(!payload)) {
> drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst state %p\n",
> port, &topology_state->base);
Ditto.
BR,
Jani.
> return -EINVAL;
> }
>
> - drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, pos->time_slots);
> - if (pos->time_slots) {
> + drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, payload->time_slots);
> + if (payload->time_slots) {
> drm_dp_mst_put_port_malloc(port);
> - pos->time_slots = 0;
> - pos->pbn = 0;
> + payload->time_slots = 0;
> + payload->pbn = 0;
> }
>
> return 0;
> @@ -5194,18 +5193,8 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
> return 0;
>
> if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
> - bool found = false;
> -
> - list_for_each_entry(payload, &state->payloads, next) {
> - if (payload->port != port)
> - continue;
> - if (!payload->pbn)
> - return 0;
> -
> - found = true;
> - break;
> - }
> - if (!found)
> + payload = drm_atomic_get_mst_payload_state(state, port);
> + if (!payload)
> return 0;
>
> /*
> @@ -5360,34 +5349,26 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
> bool enable)
> {
> struct drm_dp_mst_topology_state *mst_state;
> - struct drm_dp_mst_atomic_payload *pos;
> - bool found = false;
> + struct drm_dp_mst_atomic_payload *payload;
> int time_slots = 0;
>
> mst_state = drm_atomic_get_mst_topology_state(state, port->mgr);
> -
> if (IS_ERR(mst_state))
> return PTR_ERR(mst_state);
>
> - list_for_each_entry(pos, &mst_state->payloads, next) {
> - if (pos->port == port) {
> - found = true;
> - break;
> - }
> - }
> -
> - if (!found) {
> + payload = drm_atomic_get_mst_payload_state(mst_state, port);
> + if (!payload) {
> drm_dbg_atomic(state->dev,
> "[MST PORT:%p] Couldn't find payload in mst state %p\n",
> port, mst_state);
> return -EINVAL;
> }
>
> - if (pos->dsc_enabled == enable) {
> + if (payload->dsc_enabled == enable) {
> drm_dbg_atomic(state->dev,
> "[MST PORT:%p] DSC flag is already set to %d, returning %d time slots\n",
> - port, enable, pos->time_slots);
> - time_slots = pos->time_slots;
> + port, enable, payload->time_slots);
> + time_slots = payload->time_slots;
> }
>
> if (enable) {
> @@ -5399,7 +5380,7 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
> return -EINVAL;
> }
>
> - pos->dsc_enabled = enable;
> + payload->dsc_enabled = enable;
>
> return time_slots;
> }
--
Jani Nikula, Intel Open Source Graphics Center
WARNING: multiple messages have this Message-ID (diff)
From: Jani Nikula <jani.nikula@intel.com>
To: Lyude Paul <lyude@redhat.com>,
dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org,
amd-gfx@lists.freedesktop.org
Cc: Thomas Zimmermann <tzimmermann@suse.de>,
David Airlie <airlied@linux.ie>,
Daniel Vetter <daniel.vetter@ffwll.ch>,
open list <linux-kernel@vger.kernel.org>,
Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>,
Fangzhi Zuo <Jerry.Zuo@amd.com>, Wayne Lin <Wayne.Lin@amd.com>,
Sean Paul <sean@poorly.run>
Subject: Re: [RESEND RFC 07/18] drm/display/dp_mst: Add helper for finding payloads in atomic MST state
Date: Wed, 29 Jun 2022 16:22:07 +0300 [thread overview]
Message-ID: <87v8sjppts.fsf@intel.com> (raw)
In-Reply-To: <20220607192933.1333228-8-lyude@redhat.com>
On Tue, 07 Jun 2022, Lyude Paul <lyude@redhat.com> wrote:
> We already open-code this quite often, and will be iterating through
> payloads even more once we've moved all of the payload tracking into the
> atomic state. So, let's add a helper for doing this.
>
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> Cc: Wayne Lin <Wayne.Lin@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Fangzhi Zuo <Jerry.Zuo@amd.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Sean Paul <sean@poorly.run>
> ---
> drivers/gpu/drm/display/drm_dp_mst_topology.c | 109 ++++++++----------
> 1 file changed, 45 insertions(+), 64 deletions(-)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index ec52f91b1f0e..0bc2c7a90c37 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -1737,6 +1737,19 @@ drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port) {}
> #define save_port_topology_ref(port, type)
> #endif
>
> +static struct drm_dp_mst_atomic_payload *
> +drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state,
> + struct drm_dp_mst_port *port)
> +{
> + struct drm_dp_mst_atomic_payload *payload;
> +
> + list_for_each_entry(payload, &state->payloads, next)
> + if (payload->port == port)
> + return payload;
> +
> + return NULL;
> +}
> +
> static void drm_dp_destroy_mst_branch_device(struct kref *kref)
> {
> struct drm_dp_mst_branch *mstb =
> @@ -4381,39 +4394,31 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state,
> int pbn_div)
> {
> struct drm_dp_mst_topology_state *topology_state;
> - struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
> - int prev_slots, prev_bw, req_slots;
> + struct drm_dp_mst_atomic_payload *payload = NULL;
> + int prev_slots = 0, prev_bw = 0, req_slots;
>
> topology_state = drm_atomic_get_mst_topology_state(state, mgr);
> if (IS_ERR(topology_state))
> return PTR_ERR(topology_state);
>
> /* Find the current allocation for this port, if any */
> - list_for_each_entry(pos, &topology_state->payloads, next) {
> - if (pos->port == port) {
> - payload = pos;
> - prev_slots = payload->time_slots;
> - prev_bw = payload->pbn;
> -
> - /*
> - * This should never happen, unless the driver tries
> - * releasing and allocating the same timeslot allocation,
> - * which is an error
> - */
> - if (WARN_ON(!prev_slots)) {
> - drm_err(mgr->dev,
> - "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",
> - port);
> - return -EINVAL;
> - }
> + payload = drm_atomic_get_mst_payload_state(topology_state, port);
> + if (payload) {
> + prev_slots = payload->time_slots;
> + prev_bw = payload->pbn;
>
> - break;
> + /*
> + * This should never happen, unless the driver tries
> + * releasing and allocating the same timeslot allocation,
> + * which is an error
> + */
> + if (WARN_ON(!prev_slots)) {
> + drm_err(mgr->dev,
> + "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",
> + port);
I guess I'd combine the WARN_ON() and drm_err() to a single
drm_WARN(). Having both is a silly. But can be a follow-up, not part of
this patch really.
> + return -EINVAL;
> }
> }
> - if (!payload) {
> - prev_slots = 0;
> - prev_bw = 0;
> - }
>
> if (pbn_div <= 0)
> pbn_div = mgr->pbn_div;
> @@ -4474,30 +4479,24 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,
> struct drm_dp_mst_port *port)
> {
> struct drm_dp_mst_topology_state *topology_state;
> - struct drm_dp_mst_atomic_payload *pos;
> - bool found = false;
> + struct drm_dp_mst_atomic_payload *payload;
>
> topology_state = drm_atomic_get_mst_topology_state(state, mgr);
> if (IS_ERR(topology_state))
> return PTR_ERR(topology_state);
>
> - list_for_each_entry(pos, &topology_state->payloads, next) {
> - if (pos->port == port) {
> - found = true;
> - break;
> - }
> - }
> - if (WARN_ON(!found)) {
> + payload = drm_atomic_get_mst_payload_state(topology_state, port);
> + if (WARN_ON(!payload)) {
> drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst state %p\n",
> port, &topology_state->base);
Ditto.
BR,
Jani.
> return -EINVAL;
> }
>
> - drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, pos->time_slots);
> - if (pos->time_slots) {
> + drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, payload->time_slots);
> + if (payload->time_slots) {
> drm_dp_mst_put_port_malloc(port);
> - pos->time_slots = 0;
> - pos->pbn = 0;
> + payload->time_slots = 0;
> + payload->pbn = 0;
> }
>
> return 0;
> @@ -5194,18 +5193,8 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
> return 0;
>
> if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
> - bool found = false;
> -
> - list_for_each_entry(payload, &state->payloads, next) {
> - if (payload->port != port)
> - continue;
> - if (!payload->pbn)
> - return 0;
> -
> - found = true;
> - break;
> - }
> - if (!found)
> + payload = drm_atomic_get_mst_payload_state(state, port);
> + if (!payload)
> return 0;
>
> /*
> @@ -5360,34 +5349,26 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
> bool enable)
> {
> struct drm_dp_mst_topology_state *mst_state;
> - struct drm_dp_mst_atomic_payload *pos;
> - bool found = false;
> + struct drm_dp_mst_atomic_payload *payload;
> int time_slots = 0;
>
> mst_state = drm_atomic_get_mst_topology_state(state, port->mgr);
> -
> if (IS_ERR(mst_state))
> return PTR_ERR(mst_state);
>
> - list_for_each_entry(pos, &mst_state->payloads, next) {
> - if (pos->port == port) {
> - found = true;
> - break;
> - }
> - }
> -
> - if (!found) {
> + payload = drm_atomic_get_mst_payload_state(mst_state, port);
> + if (!payload) {
> drm_dbg_atomic(state->dev,
> "[MST PORT:%p] Couldn't find payload in mst state %p\n",
> port, mst_state);
> return -EINVAL;
> }
>
> - if (pos->dsc_enabled == enable) {
> + if (payload->dsc_enabled == enable) {
> drm_dbg_atomic(state->dev,
> "[MST PORT:%p] DSC flag is already set to %d, returning %d time slots\n",
> - port, enable, pos->time_slots);
> - time_slots = pos->time_slots;
> + port, enable, payload->time_slots);
> + time_slots = payload->time_slots;
> }
>
> if (enable) {
> @@ -5399,7 +5380,7 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
> return -EINVAL;
> }
>
> - pos->dsc_enabled = enable;
> + payload->dsc_enabled = enable;
>
> return time_slots;
> }
--
Jani Nikula, Intel Open Source Graphics Center
WARNING: multiple messages have this Message-ID (diff)
From: Jani Nikula <jani.nikula@intel.com>
To: Lyude Paul <lyude@redhat.com>,
dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org,
amd-gfx@lists.freedesktop.org
Cc: "Wayne Lin" <Wayne.Lin@amd.com>,
"Ville Syrjälä" <ville.syrjala@linux.intel.com>,
"Fangzhi Zuo" <Jerry.Zuo@amd.com>,
"Imre Deak" <imre.deak@intel.com>,
"Daniel Vetter" <daniel.vetter@ffwll.ch>,
"Sean Paul" <sean@poorly.run>, "David Airlie" <airlied@linux.ie>,
"Daniel Vetter" <daniel@ffwll.ch>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"Bhawanpreet Lakha" <Bhawanpreet.Lakha@amd.com>,
"open list" <linux-kernel@vger.kernel.org>
Subject: Re: [RESEND RFC 07/18] drm/display/dp_mst: Add helper for finding payloads in atomic MST state
Date: Wed, 29 Jun 2022 16:22:07 +0300 [thread overview]
Message-ID: <87v8sjppts.fsf@intel.com> (raw)
In-Reply-To: <20220607192933.1333228-8-lyude@redhat.com>
On Tue, 07 Jun 2022, Lyude Paul <lyude@redhat.com> wrote:
> We already open-code this quite often, and will be iterating through
> payloads even more once we've moved all of the payload tracking into the
> atomic state. So, let's add a helper for doing this.
>
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> Cc: Wayne Lin <Wayne.Lin@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Fangzhi Zuo <Jerry.Zuo@amd.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Sean Paul <sean@poorly.run>
> ---
> drivers/gpu/drm/display/drm_dp_mst_topology.c | 109 ++++++++----------
> 1 file changed, 45 insertions(+), 64 deletions(-)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index ec52f91b1f0e..0bc2c7a90c37 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -1737,6 +1737,19 @@ drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port) {}
> #define save_port_topology_ref(port, type)
> #endif
>
> +static struct drm_dp_mst_atomic_payload *
> +drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state,
> + struct drm_dp_mst_port *port)
> +{
> + struct drm_dp_mst_atomic_payload *payload;
> +
> + list_for_each_entry(payload, &state->payloads, next)
> + if (payload->port == port)
> + return payload;
> +
> + return NULL;
> +}
> +
> static void drm_dp_destroy_mst_branch_device(struct kref *kref)
> {
> struct drm_dp_mst_branch *mstb =
> @@ -4381,39 +4394,31 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state,
> int pbn_div)
> {
> struct drm_dp_mst_topology_state *topology_state;
> - struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
> - int prev_slots, prev_bw, req_slots;
> + struct drm_dp_mst_atomic_payload *payload = NULL;
> + int prev_slots = 0, prev_bw = 0, req_slots;
>
> topology_state = drm_atomic_get_mst_topology_state(state, mgr);
> if (IS_ERR(topology_state))
> return PTR_ERR(topology_state);
>
> /* Find the current allocation for this port, if any */
> - list_for_each_entry(pos, &topology_state->payloads, next) {
> - if (pos->port == port) {
> - payload = pos;
> - prev_slots = payload->time_slots;
> - prev_bw = payload->pbn;
> -
> - /*
> - * This should never happen, unless the driver tries
> - * releasing and allocating the same timeslot allocation,
> - * which is an error
> - */
> - if (WARN_ON(!prev_slots)) {
> - drm_err(mgr->dev,
> - "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",
> - port);
> - return -EINVAL;
> - }
> + payload = drm_atomic_get_mst_payload_state(topology_state, port);
> + if (payload) {
> + prev_slots = payload->time_slots;
> + prev_bw = payload->pbn;
>
> - break;
> + /*
> + * This should never happen, unless the driver tries
> + * releasing and allocating the same timeslot allocation,
> + * which is an error
> + */
> + if (WARN_ON(!prev_slots)) {
> + drm_err(mgr->dev,
> + "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",
> + port);
I guess I'd combine the WARN_ON() and drm_err() to a single
drm_WARN(). Having both is a silly. But can be a follow-up, not part of
this patch really.
> + return -EINVAL;
> }
> }
> - if (!payload) {
> - prev_slots = 0;
> - prev_bw = 0;
> - }
>
> if (pbn_div <= 0)
> pbn_div = mgr->pbn_div;
> @@ -4474,30 +4479,24 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,
> struct drm_dp_mst_port *port)
> {
> struct drm_dp_mst_topology_state *topology_state;
> - struct drm_dp_mst_atomic_payload *pos;
> - bool found = false;
> + struct drm_dp_mst_atomic_payload *payload;
>
> topology_state = drm_atomic_get_mst_topology_state(state, mgr);
> if (IS_ERR(topology_state))
> return PTR_ERR(topology_state);
>
> - list_for_each_entry(pos, &topology_state->payloads, next) {
> - if (pos->port == port) {
> - found = true;
> - break;
> - }
> - }
> - if (WARN_ON(!found)) {
> + payload = drm_atomic_get_mst_payload_state(topology_state, port);
> + if (WARN_ON(!payload)) {
> drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst state %p\n",
> port, &topology_state->base);
Ditto.
BR,
Jani.
> return -EINVAL;
> }
>
> - drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, pos->time_slots);
> - if (pos->time_slots) {
> + drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, payload->time_slots);
> + if (payload->time_slots) {
> drm_dp_mst_put_port_malloc(port);
> - pos->time_slots = 0;
> - pos->pbn = 0;
> + payload->time_slots = 0;
> + payload->pbn = 0;
> }
>
> return 0;
> @@ -5194,18 +5193,8 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
> return 0;
>
> if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
> - bool found = false;
> -
> - list_for_each_entry(payload, &state->payloads, next) {
> - if (payload->port != port)
> - continue;
> - if (!payload->pbn)
> - return 0;
> -
> - found = true;
> - break;
> - }
> - if (!found)
> + payload = drm_atomic_get_mst_payload_state(state, port);
> + if (!payload)
> return 0;
>
> /*
> @@ -5360,34 +5349,26 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
> bool enable)
> {
> struct drm_dp_mst_topology_state *mst_state;
> - struct drm_dp_mst_atomic_payload *pos;
> - bool found = false;
> + struct drm_dp_mst_atomic_payload *payload;
> int time_slots = 0;
>
> mst_state = drm_atomic_get_mst_topology_state(state, port->mgr);
> -
> if (IS_ERR(mst_state))
> return PTR_ERR(mst_state);
>
> - list_for_each_entry(pos, &mst_state->payloads, next) {
> - if (pos->port == port) {
> - found = true;
> - break;
> - }
> - }
> -
> - if (!found) {
> + payload = drm_atomic_get_mst_payload_state(mst_state, port);
> + if (!payload) {
> drm_dbg_atomic(state->dev,
> "[MST PORT:%p] Couldn't find payload in mst state %p\n",
> port, mst_state);
> return -EINVAL;
> }
>
> - if (pos->dsc_enabled == enable) {
> + if (payload->dsc_enabled == enable) {
> drm_dbg_atomic(state->dev,
> "[MST PORT:%p] DSC flag is already set to %d, returning %d time slots\n",
> - port, enable, pos->time_slots);
> - time_slots = pos->time_slots;
> + port, enable, payload->time_slots);
> + time_slots = payload->time_slots;
> }
>
> if (enable) {
> @@ -5399,7 +5380,7 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
> return -EINVAL;
> }
>
> - pos->dsc_enabled = enable;
> + payload->dsc_enabled = enable;
>
> return time_slots;
> }
--
Jani Nikula, Intel Open Source Graphics Center
next prev parent reply other threads:[~2022-06-29 14:09 UTC|newest]
Thread overview: 155+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-07 19:29 [RESEND RFC 00/18] drm/display/dp_mst: Drop Radeon MST support, make MST atomic-only Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 01/18] drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table) Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 02/18] drm/amdgpu/dm/mst: Rename get_payload_table() Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 03/18] drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 04/18] drm/display/dp_mst: Call them time slots, not VCPI slots Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [Intel-gfx] " Lyude Paul
2022-06-15 4:28 ` Lin, Wayne
2022-06-15 4:28 ` Lin, Wayne
2022-06-15 4:28 ` Lin, Wayne
2022-06-15 4:28 ` [Nouveau] " Lin, Wayne
2022-08-02 21:29 ` Lyude Paul
2022-08-02 21:29 ` Lyude Paul
2022-08-02 21:29 ` Lyude Paul
2022-08-02 21:29 ` [Nouveau] " Lyude Paul
2022-08-02 21:29 ` [Intel-gfx] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 05/18] drm/display/dp_mst: Fix confusing docs for drm_dp_atomic_release_time_slots() Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 06/18] drm/display/dp_mst: Add some missing kdocs for atomic MST structs Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-15 4:43 ` Lin, Wayne
2022-06-15 4:43 ` Lin, Wayne
2022-06-15 4:43 ` Lin, Wayne
2022-06-15 4:43 ` [Nouveau] " Lin, Wayne
2022-08-08 23:07 ` Lyude Paul
2022-08-08 23:07 ` Lyude Paul
2022-08-08 23:07 ` Lyude Paul
2022-08-08 23:07 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 07/18] drm/display/dp_mst: Add helper for finding payloads in atomic MST state Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-29 13:22 ` Jani Nikula [this message]
2022-06-29 13:22 ` Jani Nikula
2022-06-29 13:22 ` Jani Nikula
2022-06-29 13:22 ` [Nouveau] " Jani Nikula
2022-06-07 19:29 ` [RESEND RFC 08/18] drm/display/dp_mst: Add nonblocking helpers for DP MST Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [Intel-gfx] " Lyude Paul
2022-06-29 13:30 ` Jani Nikula
2022-06-29 13:30 ` Jani Nikula
2022-06-29 13:30 ` Jani Nikula
2022-06-29 13:30 ` [Nouveau] " Jani Nikula
2022-06-29 13:30 ` [Intel-gfx] " Jani Nikula
2022-06-07 19:29 ` [RESEND RFC 09/18] drm/display/dp_mst: Don't open code modeset checks for releasing time slots Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [Intel-gfx] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 10/18] drm/display/dp_mst: Fix modeset tracking in drm_dp_atomic_release_vcpi_slots() Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 11/18] drm/nouveau/kms: Cache DP encoders in nouveau_connector Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 12/18] drm/nouveau/kms: Pull mst state in for all modesets Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 13/18] drm/display/dp_mst: Add helpers for serializing SST <-> MST transitions Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [Intel-gfx] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 14/18] drm/display/dp_mst: Drop all ports from topology on CSNs before queueing link address work Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 15/18] drm/display/dp_mst: Skip releasing payloads if last connected port isn't connected Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-07-05 8:45 ` Lin, Wayne
2022-07-05 8:45 ` Lin, Wayne
2022-07-05 8:45 ` Lin, Wayne
2022-07-05 8:45 ` [Nouveau] " Lin, Wayne
2022-08-02 22:12 ` Lyude Paul
2022-08-02 22:12 ` Lyude Paul
2022-08-02 22:12 ` Lyude Paul
2022-08-02 22:12 ` [Nouveau] " Lyude Paul
2022-08-10 3:28 ` Lin, Wayne
2022-08-10 3:28 ` Lin, Wayne
2022-08-10 3:28 ` Lin, Wayne
2022-08-10 3:28 ` [Nouveau] " Lin, Wayne
2022-08-10 22:13 ` Lyude Paul
2022-08-10 22:13 ` Lyude Paul
2022-08-10 22:13 ` Lyude Paul
2022-08-10 22:13 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 16/18] drm/display/dp_mst: Maintain time slot allocations when deleting payloads Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [RESEND RFC 17/18] drm/radeon: Drop legacy MST support Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 20:48 ` Alex Deucher
2022-06-07 20:48 ` Alex Deucher
2022-06-07 20:48 ` [Nouveau] " Alex Deucher
2022-06-07 19:29 ` [RESEND RFC 18/18] drm/display/dp_mst: Move all payload info into the atomic state Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` Lyude Paul
2022-06-07 19:29 ` [Nouveau] " Lyude Paul
2022-06-07 19:29 ` [Intel-gfx] " Lyude Paul
2022-07-05 9:10 ` Lin, Wayne
2022-07-05 9:10 ` Lin, Wayne
2022-07-05 9:10 ` Lin, Wayne
2022-07-05 9:10 ` [Nouveau] " Lin, Wayne
2022-07-06 21:57 ` Lyude Paul
2022-07-06 21:57 ` Lyude Paul
2022-07-06 21:57 ` Lyude Paul
2022-07-06 21:57 ` [Nouveau] " Lyude Paul
2022-07-06 21:57 ` [Intel-gfx] " Lyude Paul
2022-08-03 20:27 ` Lyude Paul
2022-08-03 20:27 ` Lyude Paul
2022-08-03 20:27 ` Lyude Paul
2022-08-03 20:27 ` [Nouveau] " Lyude Paul
2022-08-03 20:27 ` [Intel-gfx] " Lyude Paul
2022-08-08 10:02 ` Lin, Wayne
2022-08-08 10:02 ` Lin, Wayne
2022-08-08 10:02 ` Lin, Wayne
2022-08-08 10:02 ` [Nouveau] " Lin, Wayne
2022-08-08 10:02 ` [Intel-gfx] " Lin, Wayne
2022-08-08 22:53 ` Lyude Paul
2022-08-08 22:53 ` Lyude Paul
2022-08-08 22:53 ` Lyude Paul
2022-08-08 22:53 ` [Nouveau] " Lyude Paul
2022-08-08 22:53 ` [Intel-gfx] " Lyude Paul
2022-06-29 13:33 ` [RESEND RFC 00/18] drm/display/dp_mst: Drop Radeon MST support, make MST atomic-only Jani Nikula
2022-06-29 13:33 ` Jani Nikula
2022-06-29 13:33 ` [Nouveau] " Jani Nikula
2022-07-28 22:21 ` Lyude Paul
2022-07-28 22:21 ` Lyude Paul
2022-07-28 22:21 ` [Nouveau] " Lyude Paul
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87v8sjppts.fsf@intel.com \
--to=jani.nikula@intel.com \
--cc=Bhawanpreet.Lakha@amd.com \
--cc=Jerry.Zuo@amd.com \
--cc=Wayne.Lin@amd.com \
--cc=airlied@linux.ie \
--cc=amd-gfx@lists.freedesktop.org \
--cc=daniel.vetter@ffwll.ch \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=imre.deak@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lyude@redhat.com \
--cc=nouveau@lists.freedesktop.org \
--cc=sean@poorly.run \
--cc=tzimmermann@suse.de \
--cc=ville.syrjala@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.