All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] kobject: avoid blocking allocation while holding uevent_sock_mutex
@ 2026-08-26  6:46 Tao Yu
  2026-08-26  7:01 ` Greg KH
  0 siblings, 1 reply; 4+ messages in thread
From: Tao Yu @ 2026-08-26  6:46 UTC (permalink / raw)
  To: gregkh
  Cc: rafael, dakr, akpm, driver-core, linux-kernel, Tao Yu,
	syzbot+c22bb42560ec86726aba

uevent_net_broadcast_untagged() still holds uevent_sock_mutex across
netlink_broadcast().  That serializes all untagged uevent senders behind
one global mutex, and it also keeps the mutex held while the netlink
broadcast path may perform blocking memory allocation.

This becomes visible during USB enumeration, where device_add() sends a
KOBJ_ADD uevent from the usb_hub_wq context.  If a listener is slow or
the netlink broadcast path runs into memory pressure, the sender can sit
behind uevent_sock_mutex long enough to trigger hung task reports.

Keep the existing send-side ordering, but move the uevent skb allocation
out of the critical section and use GFP_NOWAIT for the broadcast clones
performed while uevent_sock_mutex is held.  This removes the sleeping
allocation point from the locked region without changing uevent delivery
semantics.

Reported-by: syzbot+c22bb42560ec86726aba@syzkaller.appspotmail.com
Signed-off-by: Tao Yu <tao1.yu@intel.com>
---
 lib/kobject_uevent.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index ddbc4d7482d24..b8832a5ca583d 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -311,9 +311,26 @@ static int uevent_net_broadcast_untagged(struct kobj_uevent_env *env,
 {
 	struct sk_buff *skb = NULL;
 	struct uevent_sock *ue_sk;
+	bool has_listeners = false;
 	int retval = 0;
 
-	/* send netlink message */
+	mutex_lock(&uevent_sock_mutex);
+	list_for_each_entry(ue_sk, &uevent_sock_list, list) {
+		if (!netlink_has_listeners(ue_sk->sk, 1))
+			continue;
+
+		has_listeners = true;
+		break;
+	}
+	mutex_unlock(&uevent_sock_mutex);
+
+	if (has_listeners) {
+		skb = alloc_uevent_skb(env, action_string, devpath);
+		if (!skb)
+			return -ENOMEM;
+	}
+
+	/* Keep send-side ordering, but avoid sleeping while holding the mutex. */
 	mutex_lock(&uevent_sock_mutex);
 	list_for_each_entry(ue_sk, &uevent_sock_list, list) {
 		struct sock *uevent_sock = ue_sk->sk;
@@ -321,15 +338,8 @@ static int uevent_net_broadcast_untagged(struct kobj_uevent_env *env,
 		if (!netlink_has_listeners(uevent_sock, 1))
 			continue;
 
-		if (!skb) {
-			retval = -ENOMEM;
-			skb = alloc_uevent_skb(env, action_string, devpath);
-			if (!skb)
-				continue;
-		}
-
 		retval = netlink_broadcast(uevent_sock, skb_get(skb), 0, 1,
-					   GFP_KERNEL);
+					   GFP_NOWAIT);
 		/* ENOBUFS should be handled in userspace */
 		if (retval == -ENOBUFS || retval == -ESRCH)
 			retval = 0;
-- 
2.34.1


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

end of thread, other threads:[~2026-08-26  7:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-26  6:46 [PATCH] kobject: avoid blocking allocation while holding uevent_sock_mutex Tao Yu
2026-08-26  7:01 ` Greg KH
2026-08-26  7:17   ` Tao Yu
2026-08-26  7:28     ` Greg KH

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.