All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: Andrei Kuchynski <akuchynski@chromium.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jameson Thies <jthies@google.com>,
	Abhishek Pandit-Subedi <abhishekpandit@chromium.org>,
	Benson Leung <bleung@chromium.org>,
	Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>,
	Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>,
	Pooja Katiyar <pooja.katiyar@intel.com>,
	Madhu M <madhu.m@intel.com>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
Subject: Re: [PATCH v2 1/2] usb: typec: ucsi: displayport: Fix deadlock
Date: Mon, 28 Apr 2025 16:23:26 +0300	[thread overview]
Message-ID: <aA-BTrunTaYxtrps@kuha.fi.intel.com> (raw)
In-Reply-To: <20250424084429.3220757-2-akuchynski@chromium.org>

On Thu, Apr 24, 2025 at 08:44:28AM +0000, Andrei Kuchynski wrote:
> This patch introduces the ucsi_con_mutex_lock / ucsi_con_mutex_unlock
> functions to the UCSI driver. ucsi_con_mutex_lock ensures the connector
> mutex is only locked if a connection is established and the partner pointer
> is valid. This resolves a deadlock scenario where
> ucsi_displayport_remove_partner holds con->mutex waiting for
> dp_altmode_work to complete while dp_altmode_work attempts to acquire it.
> 
> Cc: stable@vger.kernel.org
> Fixes: af8622f6a585 ("usb: typec: ucsi: Support for DisplayPort alt mode")
> Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/usb/typec/ucsi/displayport.c | 19 +++++++++-------
>  drivers/usb/typec/ucsi/ucsi.c        | 34 ++++++++++++++++++++++++++++
>  drivers/usb/typec/ucsi/ucsi.h        |  2 ++
>  3 files changed, 47 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/usb/typec/ucsi/displayport.c b/drivers/usb/typec/ucsi/displayport.c
> index 420af5139c70..acd053d4e38c 100644
> --- a/drivers/usb/typec/ucsi/displayport.c
> +++ b/drivers/usb/typec/ucsi/displayport.c
> @@ -54,7 +54,8 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo)
>  	u8 cur = 0;
>  	int ret;
>  
> -	mutex_lock(&dp->con->lock);
> +	if (!ucsi_con_mutex_lock(dp->con))
> +		return -ENOTCONN;
>  
>  	if (!dp->override && dp->initialized) {
>  		const struct typec_altmode *p = typec_altmode_get_partner(alt);
> @@ -100,7 +101,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo)
>  	schedule_work(&dp->work);
>  	ret = 0;
>  err_unlock:
> -	mutex_unlock(&dp->con->lock);
> +	ucsi_con_mutex_unlock(dp->con);
>  
>  	return ret;
>  }
> @@ -112,7 +113,8 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
>  	u64 command;
>  	int ret = 0;
>  
> -	mutex_lock(&dp->con->lock);
> +	if (!ucsi_con_mutex_lock(dp->con))
> +		return -ENOTCONN;
>  
>  	if (!dp->override) {
>  		const struct typec_altmode *p = typec_altmode_get_partner(alt);
> @@ -144,7 +146,7 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
>  	schedule_work(&dp->work);
>  
>  out_unlock:
> -	mutex_unlock(&dp->con->lock);
> +	ucsi_con_mutex_unlock(dp->con);
>  
>  	return ret;
>  }
> @@ -202,20 +204,21 @@ static int ucsi_displayport_vdm(struct typec_altmode *alt,
>  	int cmd = PD_VDO_CMD(header);
>  	int svdm_version;
>  
> -	mutex_lock(&dp->con->lock);
> +	if (!ucsi_con_mutex_lock(dp->con))
> +		return -ENOTCONN;
>  
>  	if (!dp->override && dp->initialized) {
>  		const struct typec_altmode *p = typec_altmode_get_partner(alt);
>  
>  		dev_warn(&p->dev,
>  			 "firmware doesn't support alternate mode overriding\n");
> -		mutex_unlock(&dp->con->lock);
> +		ucsi_con_mutex_unlock(dp->con);
>  		return -EOPNOTSUPP;
>  	}
>  
>  	svdm_version = typec_altmode_get_svdm_version(alt);
>  	if (svdm_version < 0) {
> -		mutex_unlock(&dp->con->lock);
> +		ucsi_con_mutex_unlock(dp->con);
>  		return svdm_version;
>  	}
>  
> @@ -259,7 +262,7 @@ static int ucsi_displayport_vdm(struct typec_altmode *alt,
>  		break;
>  	}
>  
> -	mutex_unlock(&dp->con->lock);
> +	ucsi_con_mutex_unlock(dp->con);
>  
>  	return 0;
>  }
> diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
> index e8c7e9dc4930..01ce858a1a2b 100644
> --- a/drivers/usb/typec/ucsi/ucsi.c
> +++ b/drivers/usb/typec/ucsi/ucsi.c
> @@ -1922,6 +1922,40 @@ void ucsi_set_drvdata(struct ucsi *ucsi, void *data)
>  }
>  EXPORT_SYMBOL_GPL(ucsi_set_drvdata);
>  
> +/**
> + * ucsi_con_mutex_lock - Acquire the connector mutex
> + * @con: The connector interface to lock
> + *
> + * Returns true on success, false if the connector is disconnected
> + */
> +bool ucsi_con_mutex_lock(struct ucsi_connector *con)
> +{
> +	bool mutex_locked = false;
> +	bool connected = true;
> +
> +	while (connected && !mutex_locked) {
> +		mutex_locked = mutex_trylock(&con->lock) != 0;
> +		connected = UCSI_CONSTAT(con, CONNECTED);
> +		if (connected && !mutex_locked)
> +			msleep(20);
> +	}
> +
> +	connected = connected && con->partner;
> +	if (!connected && mutex_locked)
> +		mutex_unlock(&con->lock);
> +
> +	return connected;
> +}
> +
> +/**
> + * ucsi_con_mutex_unlock - Release the connector mutex
> + * @con: The connector interface to unlock
> + */
> +void ucsi_con_mutex_unlock(struct ucsi_connector *con)
> +{
> +	mutex_unlock(&con->lock);
> +}
> +
>  /**
>   * ucsi_create - Allocate UCSI instance
>   * @dev: Device interface to the PPM (Platform Policy Manager)
> diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
> index 3a2c1762bec1..9c5278a0c5d4 100644
> --- a/drivers/usb/typec/ucsi/ucsi.h
> +++ b/drivers/usb/typec/ucsi/ucsi.h
> @@ -94,6 +94,8 @@ int ucsi_register(struct ucsi *ucsi);
>  void ucsi_unregister(struct ucsi *ucsi);
>  void *ucsi_get_drvdata(struct ucsi *ucsi);
>  void ucsi_set_drvdata(struct ucsi *ucsi, void *data);
> +bool ucsi_con_mutex_lock(struct ucsi_connector *con);
> +void ucsi_con_mutex_unlock(struct ucsi_connector *con);
>  
>  void ucsi_connector_change(struct ucsi *ucsi, u8 num);
>  
> -- 
> 2.49.0.805.g082f7c87e0-goog

-- 
heikki

  reply	other threads:[~2025-04-28 13:23 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-24  8:44 [PATCH v2 0/2] Fix thread synchronization issues Andrei Kuchynski
2025-04-24  8:44 ` [PATCH v2 1/2] usb: typec: ucsi: displayport: Fix deadlock Andrei Kuchynski
2025-04-28 13:23   ` Heikki Krogerus [this message]
2025-04-24  8:44 ` [PATCH v2 2/2] usb: typec: ucsi: displayport: Fix NULL pointer access Andrei Kuchynski
2025-04-24 16:20   ` Benson Leung

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=aA-BTrunTaYxtrps@kuha.fi.intel.com \
    --to=heikki.krogerus@linux.intel.com \
    --cc=abhishekpandit@chromium.org \
    --cc=akuchynski@chromium.org \
    --cc=bleung@chromium.org \
    --cc=diogo.ivo@tecnico.ulisboa.pt \
    --cc=dmitry.baryshkov@oss.qualcomm.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jthies@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=madhu.m@intel.com \
    --cc=pooja.katiyar@intel.com \
    --cc=stable@vger.kernel.org \
    /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.