|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [Minios-devel] [PATCH RFC 14/16] Save/Restore Support: Add suspend/restore support for xenbus
Bruno Alvisio, on mar. 19 déc. 2017 15:42:09 -0800, wrote:
> Currently the watch path is not saved in the watch struct when it is
> registered.
> During xenbus resume the path is needed so that the watches can be registered
> again.
> Thus, 'path' field is added to struct watch so that watches can be
> re-registered
> during xenbus resume.
>
> Signed-off-by: Bruno Alvisio <bruno.alvisio@xxxxxxxxx>
Again, there are spurious hunks in this patch due to oddities in
indentation, please remove them. Apart from that,
Reviewed-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>
> ---
> include/xenbus.h | 2 ++
> kernel.c | 8 +++++
> xenbus/xenbus.c | 106
> +++++++++++++++++++++++++++++++++++++++----------------
> 3 files changed, 85 insertions(+), 31 deletions(-)
>
> diff --git a/include/xenbus.h b/include/xenbus.h
> index b2d5072..3871f35 100644
> --- a/include/xenbus.h
> +++ b/include/xenbus.h
> @@ -120,6 +120,8 @@ domid_t xenbus_get_self_id(void);
> #ifdef CONFIG_XENBUS
> /* Reset the XenBus system. */
> void fini_xenbus(void);
> +void suspend_xenbus(void);
> +void resume_xenbus(int canceled);
> #else
> static inline void fini_xenbus(void)
> {
> diff --git a/kernel.c b/kernel.c
> index a563f60..bc2394f 100644
> --- a/kernel.c
> +++ b/kernel.c
> @@ -119,6 +119,10 @@ void start_kernel(void* par)
>
> void pre_suspend(void)
> {
> +#ifdef CONFIG_XENBUS
> + suspend_xenbus();
> +#endif
> +
> local_irq_disable();
>
> suspend_gnttab();
> @@ -139,6 +143,10 @@ void post_suspend(int canceled)
> resume_gnttab();
>
> local_irq_enable();
> +
> +#ifdef CONFIG_XENBUS
> + resume_xenbus(canceled);
> +#endif
> }
>
> void stop_kernel(void)
> diff --git a/xenbus/xenbus.c b/xenbus/xenbus.c
> index c2d2bd1..4c626fb 100644
> --- a/xenbus/xenbus.c
> +++ b/xenbus/xenbus.c
> @@ -50,6 +50,7 @@ DECLARE_WAIT_QUEUE_HEAD(xenbus_watch_queue);
> xenbus_event_queue xenbus_events;
> static struct watch {
> char *token;
> + char *path;
> xenbus_event_queue *events;
> struct watch *next;
> } *watches;
> @@ -63,6 +64,8 @@ struct xenbus_req_info
> #define NR_REQS 32
> static struct xenbus_req_info req_info[NR_REQS];
>
> +static char *errmsg(struct xsd_sockmsg *rep);
> +
> uint32_t xenbus_evtchn;
>
> #ifdef CONFIG_PARAVIRT
> @@ -231,45 +234,39 @@ static void xenbus_thread_func(void *ign)
> struct xsd_sockmsg msg;
> unsigned prod = xenstore_buf->rsp_prod;
>
> - for (;;)
> - {
> + for (;;) {
> wait_event(xb_waitq, prod != xenstore_buf->rsp_prod);
> - while (1)
> - {
> + while (1) {
> prod = xenstore_buf->rsp_prod;
> DEBUG("Rsp_cons %d, rsp_prod %d.\n", xenstore_buf->rsp_cons,
> - xenstore_buf->rsp_prod);
> + xenstore_buf->rsp_prod);
> if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons <
> sizeof(msg))
> break;
> rmb();
> - memcpy_from_ring(xenstore_buf->rsp,
> - &msg,
> - MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
> - sizeof(msg));
> - DEBUG("Msg len %d, %d avail, id %d.\n",
> - msg.len + sizeof(msg),
> - xenstore_buf->rsp_prod - xenstore_buf->rsp_cons,
> - msg.req_id);
> + memcpy_from_ring(xenstore_buf->rsp, &msg,
> + MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
> + sizeof(msg));
> + DEBUG("Msg len %d, %d avail, id %d.\n", msg.len + sizeof(msg),
> + xenstore_buf->rsp_prod - xenstore_buf->rsp_cons,
> msg.req_id);
> +
> if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons <
> - sizeof(msg) + msg.len)
> + sizeof(msg) + msg.len)
> break;
>
> DEBUG("Message is good.\n");
>
> - if(msg.type == XS_WATCH_EVENT)
> - {
> - struct xenbus_event *event = malloc(sizeof(*event) + msg.len);
> + if (msg.type == XS_WATCH_EVENT) {
> + struct xenbus_event *event = malloc(sizeof(*event) +
> msg.len);
> xenbus_event_queue *events = NULL;
> - char *data = (char*)event + sizeof(*event);
> + char *data = (char*)event + sizeof(*event);
> struct watch *watch;
>
> - memcpy_from_ring(xenstore_buf->rsp,
> - data,
> + memcpy_from_ring(xenstore_buf->rsp, data,
> MASK_XENSTORE_IDX(xenstore_buf->rsp_cons + sizeof(msg)),
> msg.len);
>
> - event->path = data;
> - event->token = event->path + strlen(event->path) + 1;
> + event->path = data;
> + event->token = event->path + strlen(event->path) + 1;
>
> mb();
> xenstore_buf->rsp_cons += msg.len + sizeof(msg);
> @@ -288,15 +285,11 @@ static void xenbus_thread_func(void *ign)
> printk("unexpected watch token %s\n", event->token);
> free(event);
> }
> - }
> -
> - else
> - {
> + } else {
> req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
> - memcpy_from_ring(xenstore_buf->rsp,
> - req_info[msg.req_id].reply,
> - MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
> - msg.len + sizeof(msg));
> + memcpy_from_ring(xenstore_buf->rsp,
> req_info[msg.req_id].reply,
> + MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
> + msg.len + sizeof(msg));
> mb();
> xenstore_buf->rsp_cons += msg.len + sizeof(msg);
> wake_up(&req_info[msg.req_id].waitq);
> @@ -380,6 +373,55 @@ void fini_xenbus(void)
> {
> }
>
> +void suspend_xenbus(void)
> +{
> + /* Check for live requests and wait until they finish */
> + while (1)
> + {
> + spin_lock(&req_lock);
> + if (nr_live_reqs == 0)
> + break;
> + spin_unlock(&req_lock);
> + wait_event(req_wq, (nr_live_reqs == 0));
> + }
> +
> + mask_evtchn(xenbus_evtchn);
> + xenstore_buf = NULL;
> + spin_unlock(&req_lock);
> +}
> +
> +void resume_xenbus(int canceled)
> +{
> + char *msg;
> + struct watch *watch;
> + struct write_req req[2];
> + struct xsd_sockmsg *rep;
> +
> +#ifdef CONFIG_PARAVIRT
> + get_xenbus(&start_info);
> +#else
> + get_xenbus(0);
> +#endif
> + unmask_evtchn(xenbus_evtchn);
> +
> + if (!canceled) {
> + for (watch = watches; watch; watch = watch->next) {
> + req[0].data = watch->path;
> + req[0].len = strlen(watch->path) + 1;
> + req[1].data = watch->token;
> + req[1].len = strlen(watch->token) + 1;
> +
> + rep = xenbus_msg_reply(XS_WATCH, XBT_NIL, req, ARRAY_SIZE(req));
> + msg = errmsg(rep);
> + if (msg)
> + xprintk("error on XS_WATCH: %s\n", msg);
> + free(rep);
> + }
> + }
> +
> + notify_remote_via_evtchn(xenbus_evtchn);
> +}
> +
> /* Send data to xenbus. This can block. All of the requests are seen
> by xenbus as if sent atomically. The header is added
> automatically, using type %type, req_id %req_id, and trans_id
> @@ -501,7 +543,7 @@ static char *errmsg(struct xsd_sockmsg *rep)
> res[rep->len] = 0;
> free(rep);
> return res;
> -}
> +}
>
> /* Send a debug message to xenbus. Can block. */
> static void xenbus_debug_msg(const char *msg)
> @@ -601,6 +643,7 @@ char* xenbus_watch_path_token( xenbus_transaction_t xbt,
> const char *path, const
> events = &xenbus_events;
>
> watch->token = strdup(token);
> + watch->path = strdup(path);
> watch->events = events;
> watch->next = watches;
> watches = watch;
> @@ -636,6 +679,7 @@ char* xenbus_unwatch_path_token( xenbus_transaction_t
> xbt, const char *path, con
> for (prev = &watches, watch = *prev; watch; prev = &watch->next, watch =
> *prev)
> if (!strcmp(watch->token, token)) {
> free(watch->token);
> + free(watch->path);
> *prev = watch->next;
> free(watch);
> break;
> --
> 2.3.2 (Apple Git-55)
>
>
> _______________________________________________
> Minios-devel mailing list
> Minios-devel@xxxxxxxxxxxxxxxxxxxx
> https://lists.xenproject.org/mailman/listinfo/minios-devel
--
Samuel
quit When the quit statement is read, the bc processor
is terminated, regardless of where the quit state-
ment is found. For example, "if (0 == 1) quit"
will cause bc to terminate.
(Seen in the manpage for "bc". Note the "if" statement's logic)
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |