* [BACKPORT][PATCH 6.12.y 1/2] firmware: arm_ffa: Move memory allocation outside the mutex locking
@ 2025-07-08 19:42 Sudeep Holla
2025-07-08 19:42 ` [BACKPORT][PATCH 6.12.y 2/2] firmware: arm_ffa: Replace mutex with rwlock to avoid sleep in atomic context Sudeep Holla
2025-07-09 11:32 ` [BACKPORT][PATCH 6.12.y 1/2] firmware: arm_ffa: Move memory allocation outside the mutex locking Sasha Levin
0 siblings, 2 replies; 4+ messages in thread
From: Sudeep Holla @ 2025-07-08 19:42 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Sudeep Holla, stable, patches, Sasha Levin, Jens Wiklander
[ Upstream commit 27e850c88df0e25474a8caeb2903e2e90b62c1dc ]
The notifier callback node allocation is currently done while holding
the notify_lock mutex. While this is safe even if memory allocation may
sleep, we need to move the allocation outside the locked region in
preparation to move from using muxtes to rwlocks.
Move the memory allocation to avoid potential sleeping in atomic context
once the locks are moved from mutex to rwlocks.
Fixes: e0573444edbf ("firmware: arm_ffa: Add interfaces to request notification callbacks")
Message-Id: <20250528-ffa_notif_fix-v1-2-5ed7bc7f8437@arm.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 40 ++++++++++++++++---------------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index c0f3b7cdb6ed..b0d92f411334 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1141,12 +1141,11 @@ notifier_hash_node_get(u16 notify_id, enum notify_type type)
return NULL;
}
-static int
-update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
- void *cb_data, bool is_registration)
+static int update_notifier_cb(int notify_id, enum notify_type type,
+ struct notifier_cb_info *cb)
{
struct notifier_cb_info *cb_info = NULL;
- bool cb_found;
+ bool cb_found, is_registration = !!cb;
cb_info = notifier_hash_node_get(notify_id, type);
cb_found = !!cb_info;
@@ -1155,15 +1154,7 @@ update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
return -EINVAL;
if (is_registration) {
- cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
- if (!cb_info)
- return -ENOMEM;
-
- cb_info->type = type;
- cb_info->cb = cb;
- cb_info->cb_data = cb_data;
-
- hash_add(drv_info->notifier_hash, &cb_info->hnode, notify_id);
+ hash_add(drv_info->notifier_hash, &cb->hnode, notify_id);
} else {
hash_del(&cb_info->hnode);
kfree(cb_info);
@@ -1193,7 +1184,7 @@ static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
mutex_lock(&drv_info->notify_lock);
- rc = update_notifier_cb(notify_id, type, NULL, NULL, false);
+ rc = update_notifier_cb(notify_id, type, NULL);
if (rc) {
pr_err("Could not unregister notification callback\n");
mutex_unlock(&drv_info->notify_lock);
@@ -1212,6 +1203,7 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
{
int rc;
u32 flags = 0;
+ struct notifier_cb_info *cb_info = NULL;
enum notify_type type = ffa_notify_type_get(dev->vm_id);
if (ffa_notifications_disabled())
@@ -1220,24 +1212,34 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
if (notify_id >= FFA_MAX_NOTIFICATIONS)
return -EINVAL;
+ cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
+ if (!cb_info)
+ return -ENOMEM;
+
+ cb_info->type = type;
+ cb_info->cb_data = cb_data;
+ cb_info->cb = cb;
+
mutex_lock(&drv_info->notify_lock);
if (is_per_vcpu)
flags = PER_VCPU_NOTIFICATION_FLAG;
rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags);
- if (rc) {
- mutex_unlock(&drv_info->notify_lock);
- return rc;
- }
+ if (rc)
+ goto out_unlock_free;
- rc = update_notifier_cb(notify_id, type, cb, cb_data, true);
+ rc = update_notifier_cb(notify_id, type, cb_info);
if (rc) {
pr_err("Failed to register callback for %d - %d\n",
notify_id, rc);
ffa_notification_unbind(dev->vm_id, BIT(notify_id));
}
+
+out_unlock_free:
mutex_unlock(&drv_info->notify_lock);
+ if (rc)
+ kfree(cb_info);
return rc;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [BACKPORT][PATCH 6.12.y 2/2] firmware: arm_ffa: Replace mutex with rwlock to avoid sleep in atomic context
2025-07-08 19:42 [BACKPORT][PATCH 6.12.y 1/2] firmware: arm_ffa: Move memory allocation outside the mutex locking Sudeep Holla
@ 2025-07-08 19:42 ` Sudeep Holla
2025-07-09 11:32 ` Sasha Levin
2025-07-09 11:32 ` [BACKPORT][PATCH 6.12.y 1/2] firmware: arm_ffa: Move memory allocation outside the mutex locking Sasha Levin
1 sibling, 1 reply; 4+ messages in thread
From: Sudeep Holla @ 2025-07-08 19:42 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Sudeep Holla, stable, patches, Sasha Levin, Jens Wiklander,
Jérôme Forissier
[ Upstream commit 9ca7a421229bbdfbe2e1e628cff5cfa782720a10 ]
The current use of a mutex to protect the notifier hashtable accesses
can lead to issues in the atomic context. It results in the below
kernel warnings:
| BUG: sleeping function called from invalid context at kernel/locking/mutex.c:258
| in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 9, name: kworker/0:0
| preempt_count: 1, expected: 0
| RCU nest depth: 0, expected: 0
| CPU: 0 UID: 0 PID: 9 Comm: kworker/0:0 Not tainted 6.14.0 #4
| Workqueue: ffa_pcpu_irq_notification notif_pcpu_irq_work_fn
| Call trace:
| show_stack+0x18/0x24 (C)
| dump_stack_lvl+0x78/0x90
| dump_stack+0x18/0x24
| __might_resched+0x114/0x170
| __might_sleep+0x48/0x98
| mutex_lock+0x24/0x80
| handle_notif_callbacks+0x54/0xe0
| notif_get_and_handle+0x40/0x88
| generic_exec_single+0x80/0xc0
| smp_call_function_single+0xfc/0x1a0
| notif_pcpu_irq_work_fn+0x2c/0x38
| process_one_work+0x14c/0x2b4
| worker_thread+0x2e4/0x3e0
| kthread+0x13c/0x210
| ret_from_fork+0x10/0x20
To address this, replace the mutex with an rwlock to protect the notifier
hashtable accesses. This ensures that read-side locking does not sleep and
multiple readers can acquire the lock concurrently, avoiding unnecessary
contention and potential deadlocks. Writer access remains exclusive,
preserving correctness.
This change resolves warnings from lockdep about potential sleep in
atomic context.
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Reported-by: Jérôme Forissier <jerome.forissier@linaro.org>
Closes: https://github.com/OP-TEE/optee_os/issues/7394
Fixes: e0573444edbf ("firmware: arm_ffa: Add interfaces to request notification callbacks")
Message-Id: <20250528-ffa_notif_fix-v1-3-5ed7bc7f8437@arm.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Tested-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index b0d92f411334..83dad9c2da06 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -110,7 +110,7 @@ struct ffa_drv_info {
struct work_struct sched_recv_irq_work;
struct xarray partition_info;
DECLARE_HASHTABLE(notifier_hash, ilog2(FFA_MAX_NOTIFICATIONS));
- struct mutex notify_lock; /* lock to protect notifier hashtable */
+ rwlock_t notify_lock; /* lock to protect notifier hashtable */
};
static struct ffa_drv_info *drv_info;
@@ -1182,18 +1182,18 @@ static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
if (notify_id >= FFA_MAX_NOTIFICATIONS)
return -EINVAL;
- mutex_lock(&drv_info->notify_lock);
+ write_lock(&drv_info->notify_lock);
rc = update_notifier_cb(notify_id, type, NULL);
if (rc) {
pr_err("Could not unregister notification callback\n");
- mutex_unlock(&drv_info->notify_lock);
+ write_unlock(&drv_info->notify_lock);
return rc;
}
rc = ffa_notification_unbind(dev->vm_id, BIT(notify_id));
- mutex_unlock(&drv_info->notify_lock);
+ write_unlock(&drv_info->notify_lock);
return rc;
}
@@ -1220,7 +1220,7 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
cb_info->cb_data = cb_data;
cb_info->cb = cb;
- mutex_lock(&drv_info->notify_lock);
+ write_lock(&drv_info->notify_lock);
if (is_per_vcpu)
flags = PER_VCPU_NOTIFICATION_FLAG;
@@ -1237,7 +1237,7 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
}
out_unlock_free:
- mutex_unlock(&drv_info->notify_lock);
+ write_unlock(&drv_info->notify_lock);
if (rc)
kfree(cb_info);
@@ -1269,9 +1269,9 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
if (!(bitmap & 1))
continue;
- mutex_lock(&drv_info->notify_lock);
+ read_lock(&drv_info->notify_lock);
cb_info = notifier_hash_node_get(notify_id, type);
- mutex_unlock(&drv_info->notify_lock);
+ read_unlock(&drv_info->notify_lock);
if (cb_info && cb_info->cb)
cb_info->cb(notify_id, cb_info->cb_data);
@@ -1721,7 +1721,7 @@ static void ffa_notifications_setup(void)
goto cleanup;
hash_init(drv_info->notifier_hash);
- mutex_init(&drv_info->notify_lock);
+ rwlock_init(&drv_info->notify_lock);
drv_info->notif_enabled = true;
return;
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [BACKPORT][PATCH 6.12.y 1/2] firmware: arm_ffa: Move memory allocation outside the mutex locking
2025-07-08 19:42 [BACKPORT][PATCH 6.12.y 1/2] firmware: arm_ffa: Move memory allocation outside the mutex locking Sudeep Holla
2025-07-08 19:42 ` [BACKPORT][PATCH 6.12.y 2/2] firmware: arm_ffa: Replace mutex with rwlock to avoid sleep in atomic context Sudeep Holla
@ 2025-07-09 11:32 ` Sasha Levin
1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2025-07-09 11:32 UTC (permalink / raw)
To: stable; +Cc: Sudeep Holla, Sasha Levin
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected.
No action required from the submitter.
The upstream commit SHA1 provided is correct: 27e850c88df0e25474a8caeb2903e2e90b62c1dc
Status in newer kernel trees:
6.15.y | Present (different SHA1: 59bc31bc48c5)
Note: The patch differs from the upstream commit:
---
1: 27e850c88df0e < -: ------------- firmware: arm_ffa: Move memory allocation outside the mutex locking
-: ------------- > 1: df64e51d4ab83 Linux 6.12.36
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.12.y | Success | Success |
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [BACKPORT][PATCH 6.12.y 2/2] firmware: arm_ffa: Replace mutex with rwlock to avoid sleep in atomic context
2025-07-08 19:42 ` [BACKPORT][PATCH 6.12.y 2/2] firmware: arm_ffa: Replace mutex with rwlock to avoid sleep in atomic context Sudeep Holla
@ 2025-07-09 11:32 ` Sasha Levin
0 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2025-07-09 11:32 UTC (permalink / raw)
To: stable; +Cc: Sudeep Holla, Sasha Levin
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected.
No action required from the submitter.
The upstream commit SHA1 provided is correct: 9ca7a421229bbdfbe2e1e628cff5cfa782720a10
Status in newer kernel trees:
6.15.y | Present (different SHA1: 6dd05bec4179)
Note: The patch differs from the upstream commit:
---
1: 9ca7a421229bb < -: ------------- firmware: arm_ffa: Replace mutex with rwlock to avoid sleep in atomic context
-: ------------- > 1: df64e51d4ab83 Linux 6.12.36
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.15.y | Success | Success |
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-07-09 11:32 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-08 19:42 [BACKPORT][PATCH 6.12.y 1/2] firmware: arm_ffa: Move memory allocation outside the mutex locking Sudeep Holla
2025-07-08 19:42 ` [BACKPORT][PATCH 6.12.y 2/2] firmware: arm_ffa: Replace mutex with rwlock to avoid sleep in atomic context Sudeep Holla
2025-07-09 11:32 ` Sasha Levin
2025-07-09 11:32 ` [BACKPORT][PATCH 6.12.y 1/2] firmware: arm_ffa: Move memory allocation outside the mutex locking Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).