All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Richard Maina <quic_rmaina@quicinc.com>,
	Bjorn Andersson <andersson@kernel.org>,
	Chris Lew <quic_clew@quicinc.com>,
	Sasha Levin <sashal@kernel.org>,
	peterz@infradead.org, mingo@redhat.com, will@kernel.org,
	corbet@lwn.net, linux-remoteproc@vger.kernel.org,
	linux-doc@vger.kernel.org
Subject: [PATCH AUTOSEL 5.10 20/38] hwspinlock: Introduce hwspin_lock_bust()
Date: Wed, 31 Jul 2024 20:35:26 -0400	[thread overview]
Message-ID: <20240801003643.3938534-20-sashal@kernel.org> (raw)
In-Reply-To: <20240801003643.3938534-1-sashal@kernel.org>

From: Richard Maina <quic_rmaina@quicinc.com>

[ Upstream commit 7c327d56597d8de1680cf24e956b704270d3d84a ]

When a remoteproc crashes or goes down unexpectedly this can result in
a state where locks held by the remoteproc will remain locked possibly
resulting in deadlock. This new API hwspin_lock_bust() allows
hwspinlock implementers to define a bust operation for freeing previously
acquired hwspinlocks after verifying ownership of the acquired lock.

Signed-off-by: Richard Maina <quic_rmaina@quicinc.com>
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Chris Lew <quic_clew@quicinc.com>
Link: https://lore.kernel.org/r/20240529-hwspinlock-bust-v3-1-c8b924ffa5a2@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 Documentation/locking/hwspinlock.rst     | 11 ++++++++++
 drivers/hwspinlock/hwspinlock_core.c     | 28 ++++++++++++++++++++++++
 drivers/hwspinlock/hwspinlock_internal.h |  3 +++
 include/linux/hwspinlock.h               |  6 +++++
 4 files changed, 48 insertions(+)

diff --git a/Documentation/locking/hwspinlock.rst b/Documentation/locking/hwspinlock.rst
index 6f03713b70039..2ffaa3cbd63f1 100644
--- a/Documentation/locking/hwspinlock.rst
+++ b/Documentation/locking/hwspinlock.rst
@@ -85,6 +85,17 @@ is already free).
 
 Should be called from a process context (might sleep).
 
+::
+
+  int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id);
+
+After verifying the owner of the hwspinlock, release a previously acquired
+hwspinlock; returns 0 on success, or an appropriate error code on failure
+(e.g. -EOPNOTSUPP if the bust operation is not defined for the specific
+hwspinlock).
+
+Should be called from a process context (might sleep).
+
 ::
 
   int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout);
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index fd5f5c5a5244d..425597151dd3e 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -302,6 +302,34 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 }
 EXPORT_SYMBOL_GPL(__hwspin_unlock);
 
+/**
+ * hwspin_lock_bust() - bust a specific hwspinlock
+ * @hwlock: a previously-acquired hwspinlock which we want to bust
+ * @id: identifier of the remote lock holder, if applicable
+ *
+ * This function will bust a hwspinlock that was previously acquired as
+ * long as the current owner of the lock matches the id given by the caller.
+ *
+ * Context: Process context.
+ *
+ * Returns: 0 on success, or -EINVAL if the hwspinlock does not exist, or
+ * the bust operation fails, and -EOPNOTSUPP if the bust operation is not
+ * defined for the hwspinlock.
+ */
+int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id)
+{
+	if (WARN_ON(!hwlock))
+		return -EINVAL;
+
+	if (!hwlock->bank->ops->bust) {
+		pr_err("bust operation not defined\n");
+		return -EOPNOTSUPP;
+	}
+
+	return hwlock->bank->ops->bust(hwlock, id);
+}
+EXPORT_SYMBOL_GPL(hwspin_lock_bust);
+
 /**
  * of_hwspin_lock_simple_xlate - translate hwlock_spec to return a lock id
  * @bank: the hwspinlock device bank
diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h
index 29892767bb7a0..f298fc0ee5adb 100644
--- a/drivers/hwspinlock/hwspinlock_internal.h
+++ b/drivers/hwspinlock/hwspinlock_internal.h
@@ -21,6 +21,8 @@ struct hwspinlock_device;
  * @trylock: make a single attempt to take the lock. returns 0 on
  *	     failure and true on success. may _not_ sleep.
  * @unlock:  release the lock. always succeed. may _not_ sleep.
+ * @bust:    optional, platform-specific bust handler, called by hwspinlock
+ *	     core to bust a specific lock.
  * @relax:   optional, platform-specific relax handler, called by hwspinlock
  *	     core while spinning on a lock, between two successive
  *	     invocations of @trylock. may _not_ sleep.
@@ -28,6 +30,7 @@ struct hwspinlock_device;
 struct hwspinlock_ops {
 	int (*trylock)(struct hwspinlock *lock);
 	void (*unlock)(struct hwspinlock *lock);
+	int (*bust)(struct hwspinlock *lock, unsigned int id);
 	void (*relax)(struct hwspinlock *lock);
 };
 
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index bfe7c1f1ac6d1..f0231dbc47771 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -68,6 +68,7 @@ int __hwspin_lock_timeout(struct hwspinlock *, unsigned int, int,
 int __hwspin_trylock(struct hwspinlock *, int, unsigned long *);
 void __hwspin_unlock(struct hwspinlock *, int, unsigned long *);
 int of_hwspin_lock_get_id_byname(struct device_node *np, const char *name);
+int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id);
 int devm_hwspin_lock_free(struct device *dev, struct hwspinlock *hwlock);
 struct hwspinlock *devm_hwspin_lock_request(struct device *dev);
 struct hwspinlock *devm_hwspin_lock_request_specific(struct device *dev,
@@ -127,6 +128,11 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 {
 }
 
+static inline int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id)
+{
+	return 0;
+}
+
 static inline int of_hwspin_lock_get_id(struct device_node *np, int index)
 {
 	return 0;
-- 
2.43.0


  parent reply	other threads:[~2024-08-01  0:38 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-01  0:35 [PATCH AUTOSEL 5.10 01/38] drm/amdgpu: fix overflowed array index read warning Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 02/38] drm/amd/pm: fix warning using uninitialized value of max_vid_step Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 03/38] drm/amd/pm: fix the Out-of-bounds read warning Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 04/38] drm/amdgpu: fix uninitialized scalar variable warning Sasha Levin
2024-08-22 11:00   ` Pavel Machek
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 05/38] drm/amd/display: Check gpio_id before used as array index Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 06/38] drm/amd/display: Stop amdgpu_dm initialize when stream nums greater than 6 Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 07/38] drm/amd/display: Add array index check for hdcp ddc access Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 08/38] drm/amd/display: Check num_valid_sets before accessing reader_wm_sets[] Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 09/38] drm/amd/display: Check msg_id before processing transcation Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 10/38] drm/amd/display: Fix Coverity INTEGER_OVERFLOW within dal_gpio_service_create Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 11/38] drm/amdgpu: Fix out-of-bounds write warning Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 12/38] drm/amdgpu: Fix out-of-bounds read of df_v1_7_channel_number Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 13/38] drm/amdgpu: fix ucode out-of-bounds read warning Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 14/38] drm/amdgpu: fix mc_data " Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 15/38] drm/amdkfd: Reconcile the definition and use of oem_id in struct kfd_topology_device Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 16/38] drm/amdgpu/pm: Check input value for CUSTOM profile mode setting on legacy SOCs Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 17/38] drm/amdgpu: the warning dereferencing obj for nbio_v7_4 Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 18/38] bpf, net: Use DEV_STAT_INC() Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 19/38] PCI: al: Check IORESOURCE_BUS existence during probe Sasha Levin
2024-08-01  0:35 ` Sasha Levin [this message]
2024-08-27 12:25   ` [PATCH AUTOSEL 5.10 20/38] hwspinlock: Introduce hwspin_lock_bust() Pavel Machek
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 21/38] gpiolib: cdev: Add INIT_KFIFO() for linereq events Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 22/38] smack: tcp: ipv4, fix incorrect labeling Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 23/38] wifi: cfg80211: make hash table duplicates more survivable Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 24/38] drm/amd/display: added NULL check at start of dc_validate_stream Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 25/38] drm/amd/display: Skip wbscl_set_scaler_filter if filter is null Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 26/38] ALSA: vmaster: Return error for invalid input values Sasha Levin
2024-08-27 12:26   ` Pavel Machek
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 27/38] ELF: fix kernel.randomize_va_space double read Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 28/38] udf: Avoid excessive partition lengths Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 29/38] riscv: mm: Take memory hotplug read-lock during kernel page table dump Sasha Levin
2024-08-01  0:35   ` Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 30/38] usb: uas: set host status byte on data completion error Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 31/38] cgroup: Protect css->cgroup write under css_set_lock Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 32/38] um: line: always fill *error_out in setup_one_line() Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 33/38] devres: Initialize an uninitialized struct member Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 34/38] pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv Sasha Levin
2024-08-01  0:35   ` Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 35/38] hwmon: (lm95234) Fix underflows seen when writing limit attributes Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 36/38] hwmon: (w83627ehf) " Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 37/38] libbpf: Add NULL checks to bpf_object__{prev_map,next_map} Sasha Levin
2024-08-01  0:35 ` [PATCH AUTOSEL 5.10 38/38] wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id() Sasha Levin

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=20240801003643.3938534-20-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=andersson@kernel.org \
    --cc=corbet@lwn.net \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-remoteproc@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=quic_clew@quicinc.com \
    --cc=quic_rmaina@quicinc.com \
    --cc=stable@vger.kernel.org \
    --cc=will@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.