Messages in this thread Patch in this message | | | From | Dongli Zhang <> | Subject | [PATCH 3/6] xenbus: dispatch per-domU watch event to per-domU xenwatch thread | Date | Fri, 14 Sep 2018 15:34:13 +0800 |
| |
This is the 3rd patch of a (6-patch) patch set.
This patch dispatches the watch event to per-domU xenwatch thread when the event meets all of below conditions:
1. The watch is registered to use xenwatch multithreading feature and the get_domid() method returns valid domid. 2. There is xenwatch thread (mtwatch domain) available for the domid obtained from get_domid() method. 3. The xenwatch thread is forked successfully by kthread_run() during initialization and therefore its state should be MTWATCH_DOMAIN_UP.
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com> --- drivers/xen/xenbus/xenbus_xs.c | 53 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-)
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index 741dc54..7335e19 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -896,6 +896,32 @@ static struct xenbus_watch *find_watch(const char *token) return NULL; } +static int xs_watch_insert_event(struct xs_watch_event *event, domid_t domid) +{ + struct mtwatch_domain *domain; + int ret = -1; + + rcu_read_lock(); + + domain = mtwatch_find_domain(domid); + if (!domain) { + rcu_read_unlock(); + return ret; + } + + spin_lock(&domain->events_lock); + if (domain->state == MTWATCH_DOMAIN_UP) { + list_add_tail(&event->list, &domain->events); + wake_up(&domain->events_wq); + ret = 0; + } + spin_unlock(&domain->events_lock); + + rcu_read_unlock(); + + return ret; +} + int xs_watch_msg(struct xs_watch_event *event) { if (count_strings(event->body, event->len) != 2) { @@ -908,10 +934,29 @@ int xs_watch_msg(struct xs_watch_event *event) spin_lock(&watches_lock); event->handle = find_watch(event->token); if (event->handle != NULL) { - spin_lock(&watch_events_lock); - list_add_tail(&event->list, &watch_events); - wake_up(&watch_events_waitq); - spin_unlock(&watch_events_lock); + domid_t domid = 0; + + if (xen_mtwatch && event->handle->get_domid) + domid = event->handle->get_domid(event->handle, + event->path, + event->token); + + /* + * The event is processed by default xenwatch thread if: + * + * 1. The watch does not use xenwatch multithreading. + * 2. There is no per-domU xenwatch thread (or mtwatch + * domain) available for this domid. + * 3. The per-domU xenwatch thread is not created + * successfully by kthread_run() during initialization. + */ + if (!(domid && + xs_watch_insert_event(event, domid) == 0)) { + spin_lock(&watch_events_lock); + list_add_tail(&event->list, &watch_events); + wake_up(&watch_events_waitq); + spin_unlock(&watch_events_lock); + } } else kfree(event); spin_unlock(&watches_lock); -- 2.7.4
| |