FAILED: patch "[PATCH] xen/xenbus: Count pending messages for each watch" failed to apply to 4.9-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 3dc86ca6b4c8cfcba9da7996189d1b5a358a94fc Mon Sep 17 00:00:00 2001
From: SeongJae Park <[email protected]>
Date: Mon, 14 Dec 2020 10:07:13 +0100
Subject: [PATCH] xen/xenbus: Count pending messages for each watch
This commit adds a counter of pending messages for each watch in the struct. It is used to skip unnecessary pending messages lookup in 'unregister_xenbus_watch()'. It could also be used in 'will_handle' callback.
This is part of XSA-349
drivers/xen/xenbus/xenbus_xs.c +18 -11
@@ -711,6 +711,7 @@ int xs_watch_msg(struct xs_watch_event *event) event->path, event->token))) {spin_lock (&watch_events_lock);list_add_tail (&event->list, &watch_events); + event->handle->nr_pending++;wake_up (&watch_events_waitq);spin_unlock (&watch_events_lock); } else
@@ -768,6 +769,8 @@ int register_xenbus_watch(struct xenbus_watch *watch)sprintf (token,"%lX" , (long )watch); + watch->nr_pending =0 ; +down_read (&xs_watch_rwsem);spin_lock (&watches_lock);
@@ -817,11 +820,14 @@ void unregister_xenbus_watch(struct xenbus_watch *watch)/* Cancel pending watch events. */ spin_lock (&watch_events_lock); -list_for_each_entry_safe (event, tmp, &watch_events, list) { -if (event->handle != watch) -continue ; -list_del (&event->list); -kfree (event); +if (watch->nr_pending) { +list_for_each_entry_safe (event, tmp, &watch_events, list) { +if (event->handle != watch) +continue ; +list_del (&event->list); +kfree (event); + } + watch->nr_pending =0 ; }spin_unlock (&watch_events_lock);
@@ -868,7 +874,6 @@ void xs_suspend_cancel(void)static int xenwatch_thread (void *unused) { -struct list_head *ent;struct xs_watch_event *event; xenwatch_pid = current->pid;
@@ -883,13 +888,15 @@ static int xenwatch_thread(void *unused)mutex_lock (&xenwatch_mutex);spin_lock (&watch_events_lock); - ent = watch_events.next; -if (ent != &watch_events) -list_del (ent); + event =list_first_entry_or_null (&watch_events, + struct xs_watch_event, list); +if (event) { +list_del (&event->list); + event->handle->nr_pending--; + }spin_unlock (&watch_events_lock); -if (ent != &watch_events) { - event = list_entry(ent, struct xs_watch_event, list); +if (event) { event->handle->callback (event->handle, event->path, event->token);kfree (event);
include/xen/xenbus.h +2 -0
@@ -61,6 +61,8 @@ struct xenbus_watch/* Path being watched. */ const char *node; +unsigned int nr_pending; +/* * Called just before enqueing new event while a spinlock is held. * The event will be discarded if this callback returns false.