Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction
Wei Liu writes ("Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction"): > On Mon, Feb 12, 2018 at 03:24:26PM +, Julien Grall wrote: > > In any case, the worst that could happen is the unmap is called twice on the > > same region. So you would get spurious error message. Not that bad. > > Yeah, not that bad. Not going to be a security issue, not going to leak > resources in the end. > > To avoid spurious unmap, can we maybe unmap the pages after the xenstore > transaction is committed? In that case, only the successful one gets to > unmap, the ones that aren't committed will bail. > > (Just tossing around ideas) It should be the other way around. Because, your way, if your process crashes for some reason between the xenstore commit and the unmap, the memory is leaked. Instead, do the unmap first. Check the error code to see if it means "this was already unmapped" and if so report that only via a debug log message. Ian. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction
On Mon, Feb 12, 2018 at 03:24:26PM +, Julien Grall wrote: > > > On 12/02/18 15:17, Zhongze Liu wrote: > > Hi Julien, > > Hi, > > > > > 2018-02-12 23:09 GMT+08:00 Julien Grall: > > > Hi, > > > > > > On 12/02/18 14:52, Zhongze Liu wrote: > > > > > > > > 2018-02-08 0:54 GMT+08:00 Julien Grall : > > > > > > > > > > On 07/02/18 16:27, Zhongze Liu wrote: > > > > > > > > It seems that I mistakenly use transaction as a global lock. Now I don't > > > > have > > > > any reasons not putting the unmap out of the transaction, but this will > > > > break > > > > the original transaction into two, and I do think that we need some > > > > explicit > > > > locking here. > > > > > > > > > Can you explain why you need specific locking here? What are you trying to > > > protect? Are you trying to protect against two process doing the unmap? > > > > > > > Yes. > > I don't think you have to worry about the locking here. With the current > interface, the regions cannot be modified after the guest has booted. So the > addresses will always stay valid. > > This code path should never be called concurrently, as a lot of code in > libxl, so I think someone else will take care about that for you (I will let > Wei confirm here). > > In any case, the worst that could happen is the unmap is called twice on the > same region. So you would get spurious error message. Not that bad. Yeah, not that bad. Not going to be a security issue, not going to leak resources in the end. To avoid spurious unmap, can we maybe unmap the pages after the xenstore transaction is committed? In that case, only the successful one gets to unmap, the ones that aren't committed will bail. (Just tossing around ideas) Wei. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction
On Mon, Feb 12, 2018 at 03:24:26PM +, Julien Grall wrote: > > > On 12/02/18 15:17, Zhongze Liu wrote: > > Hi Julien, > > Hi, > > > > > 2018-02-12 23:09 GMT+08:00 Julien Grall: > > > Hi, > > > > > > On 12/02/18 14:52, Zhongze Liu wrote: > > > > > > > > 2018-02-08 0:54 GMT+08:00 Julien Grall : > > > > > > > > > > On 07/02/18 16:27, Zhongze Liu wrote: > > > > > > > > It seems that I mistakenly use transaction as a global lock. Now I don't > > > > have > > > > any reasons not putting the unmap out of the transaction, but this will > > > > break > > > > the original transaction into two, and I do think that we need some > > > > explicit > > > > locking here. > > > > > > > > > Can you explain why you need specific locking here? What are you trying to > > > protect? Are you trying to protect against two process doing the unmap? > > > > > > > Yes. > > I don't think you have to worry about the locking here. With the current > interface, the regions cannot be modified after the guest has booted. So the > addresses will always stay valid. > > This code path should never be called concurrently, as a lot of code in > libxl, so I think someone else will take care about that for you (I will let > Wei confirm here). I think you mean "can be called concurrently but locking is taken care of". If two processes / threads with different libxl ctx (not just xl. xl has a global lock) try to manipulate the same domain, libxl APIs use file locks. For the same same process, multiple threads but sharing one libxl_ctx there is pthread mutex in libxl_ctx. In a way, "someone else" (in libxl code) has already taken care of the locking. Fundamentally We need to assume the code can be called concurrently. It would be good thing if this is taken into consideration if new code is added. Wei. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction
On 12/02/18 15:17, Zhongze Liu wrote: Hi Julien, Hi, 2018-02-12 23:09 GMT+08:00 Julien Grall: Hi, On 12/02/18 14:52, Zhongze Liu wrote: 2018-02-08 0:54 GMT+08:00 Julien Grall : On 07/02/18 16:27, Zhongze Liu wrote: It seems that I mistakenly use transaction as a global lock. Now I don't have any reasons not putting the unmap out of the transaction, but this will break the original transaction into two, and I do think that we need some explicit locking here. Can you explain why you need specific locking here? What are you trying to protect? Are you trying to protect against two process doing the unmap? Yes. I don't think you have to worry about the locking here. With the current interface, the regions cannot be modified after the guest has booted. So the addresses will always stay valid. This code path should never be called concurrently, as a lot of code in libxl, so I think someone else will take care about that for you (I will let Wei confirm here). In any case, the worst that could happen is the unmap is called twice on the same region. So you would get spurious error message. Not that bad. Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction
Hi Julien an Wei, 2018-02-08 0:54 GMT+08:00 Julien Grall: > On 07/02/18 16:27, Zhongze Liu wrote: >> >> Hi Wei and Julien, > > > Hi, > > >> 2018-02-07 2:06 GMT+08:00 Wei Liu : >>> >>> On Tue, Feb 06, 2018 at 01:24:30PM +, Julien Grall wrote: > >if (libxl__device_pci_destroy_all(gc, domid) < 0) >LOGD(ERROR, domid, "Pci shutdown failed"); >rc = xc_domain_pause(ctx->xch, domid); > diff --git a/tools/libxl/libxl_internal.h > b/tools/libxl/libxl_internal.h > index 2cfe4c08a7..c398b6a6b8 100644 > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h > @@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char > **s) >_hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid, >libxl_static_shm *sshm, int len); > +_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid); > + >_hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, > libxl_static_shm *sshms, int > len); >_hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid, > diff --git a/tools/libxl/libxl_sshm.c b/tools/libxl/libxl_sshm.c > index 562f46f299..1bf4d4c2dc 100644 > --- a/tools/libxl/libxl_sshm.c > +++ b/tools/libxl/libxl_sshm.c > @@ -86,6 +86,112 @@ int libxl__sshm_check_overlap(libxl__gc *gc, > uint32_t domid, >return 0; >} > +/* Decrease the refcount of an sshm. When refcount reaches 0, NIT: Libxl coding style regarding the comment seems to be uncleared (Ian, Wei?). But I feel keep /* and */ in separate line is nicer. >>> >>> >>> I don't have an opinion here. >>> > + * clean up the whole sshm path. > + */ > +static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt, > + const char *sshm_path) > +static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt, > + uint32_t domid, const char *id, bool > isretry) > +{ > +const char *slave_path, *begin_str, *end_str; > +uint64_t begin, end; > + > +slave_path = GCSPRINTF("%s/slaves/%"PRIu32, SSHM_PATH(id), domid); > + > +begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", > slave_path)); > +end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path)); > +begin = strtoull(begin_str, NULL, 16); > +end = strtoull(end_str, NULL, 16); > + > +/* Avoid calling do_unmap many times in case of xs transaction > retry */ > +if (!isretry) > +libxl__sshm_do_unmap(gc, domid, id, begin, end); IHMO, by unmapping the regions in middle of the transaction, you increase the potential failure of it. I would move that out of the transaction path. I would be interested to hear the opinion of the tools maintainers here. >>> >>> If you move the unmap after the loop you create a window in which >>> the pages are still mapped but the toolstack thinks they are unmapped. >>> >>> While the code as-is now makes sure (assuming no error in unmap) the >>> pages are unmapped no later than the transaction is committed. I think >>> this can be done by moving unmap before the transaction. >>> >>> Zhongze, do you think the unmap must be done inside the loop? What kind >>> of invariants do you have in mind? >>> >>> Then there is the question of "what do we do if unmap fails". Honestly I >>> don't have an answer. It seems rather screwed up in that case and I >>> doubt there is much libxl can do to rectify things. >>> >> >> I put the unmap inside the transaction because I want to make the whole >> read_mapping_info->unmap->update_mapping_info process atomic. If >> I put unmap outside the transaction: after I read out the information >> that I need to do the unmap, and before I do the unmap and decrease the >> refcnt, there could be another instance of this code trying to do the same >> thing, which might lead to race condition. > > > AFAIU, the transaction is not a "global" lock. You will just not see the the > change from the others during the transactions. Your changes will be only be > visible at the end. So two transaction can be happily started concurrently, > and try to do the unmap together. Not even your code will protect against > that. > > So can you give a bit more details here? > It seems that I mistakenly use transaction as a global lock. Now I don't have any reasons not putting the unmap out of the transaction, but this will break the original transaction into two, and I do think that we need some explicit locking here. @Wei. Do you have any suggestions here? Cheers, Zhongze Liu ___ Xen-devel mailing list Xen-devel@lists.xenproject.org
Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction
On 07/02/18 16:27, Zhongze Liu wrote: Hi Wei and Julien, Hi, 2018-02-07 2:06 GMT+08:00 Wei Liu: On Tue, Feb 06, 2018 at 01:24:30PM +, Julien Grall wrote: if (libxl__device_pci_destroy_all(gc, domid) < 0) LOGD(ERROR, domid, "Pci shutdown failed"); rc = xc_domain_pause(ctx->xch, domid); diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 2cfe4c08a7..c398b6a6b8 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char **s) _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid, libxl_static_shm *sshm, int len); +_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid); + _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, libxl_static_shm *sshms, int len); _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid, diff --git a/tools/libxl/libxl_sshm.c b/tools/libxl/libxl_sshm.c index 562f46f299..1bf4d4c2dc 100644 --- a/tools/libxl/libxl_sshm.c +++ b/tools/libxl/libxl_sshm.c @@ -86,6 +86,112 @@ int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, return 0; } +/* Decrease the refcount of an sshm. When refcount reaches 0, NIT: Libxl coding style regarding the comment seems to be uncleared (Ian, Wei?). But I feel keep /* and */ in separate line is nicer. I don't have an opinion here. + * clean up the whole sshm path. + */ +static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt, + const char *sshm_path) +static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt, + uint32_t domid, const char *id, bool isretry) +{ +const char *slave_path, *begin_str, *end_str; +uint64_t begin, end; + +slave_path = GCSPRINTF("%s/slaves/%"PRIu32, SSHM_PATH(id), domid); + +begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", slave_path)); +end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path)); +begin = strtoull(begin_str, NULL, 16); +end = strtoull(end_str, NULL, 16); + +/* Avoid calling do_unmap many times in case of xs transaction retry */ +if (!isretry) +libxl__sshm_do_unmap(gc, domid, id, begin, end); IHMO, by unmapping the regions in middle of the transaction, you increase the potential failure of it. I would move that out of the transaction path. I would be interested to hear the opinion of the tools maintainers here. If you move the unmap after the loop you create a window in which the pages are still mapped but the toolstack thinks they are unmapped. While the code as-is now makes sure (assuming no error in unmap) the pages are unmapped no later than the transaction is committed. I think this can be done by moving unmap before the transaction. Zhongze, do you think the unmap must be done inside the loop? What kind of invariants do you have in mind? Then there is the question of "what do we do if unmap fails". Honestly I don't have an answer. It seems rather screwed up in that case and I doubt there is much libxl can do to rectify things. I put the unmap inside the transaction because I want to make the whole read_mapping_info->unmap->update_mapping_info process atomic. If I put unmap outside the transaction: after I read out the information that I need to do the unmap, and before I do the unmap and decrease the refcnt, there could be another instance of this code trying to do the same thing, which might lead to race condition. AFAIU, the transaction is not a "global" lock. You will just not see the the change from the others during the transactions. Your changes will be only be visible at the end. So two transaction can be happily started concurrently, and try to do the unmap together. Not even your code will protect against that. So can you give a bit more details here? Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction
Hi Wei and Julien, 2018-02-07 2:06 GMT+08:00 Wei Liu: > On Tue, Feb 06, 2018 at 01:24:30PM +, Julien Grall wrote: >> > if (libxl__device_pci_destroy_all(gc, domid) < 0) >> > LOGD(ERROR, domid, "Pci shutdown failed"); >> > rc = xc_domain_pause(ctx->xch, domid); >> > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h >> > index 2cfe4c08a7..c398b6a6b8 100644 >> > --- a/tools/libxl/libxl_internal.h >> > +++ b/tools/libxl/libxl_internal.h >> > @@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char **s) >> > _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid, >> > libxl_static_shm *sshm, int len); >> > +_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid); >> > + >> > _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, >> > libxl_static_shm *sshms, int len); >> > _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid, >> > diff --git a/tools/libxl/libxl_sshm.c b/tools/libxl/libxl_sshm.c >> > index 562f46f299..1bf4d4c2dc 100644 >> > --- a/tools/libxl/libxl_sshm.c >> > +++ b/tools/libxl/libxl_sshm.c >> > @@ -86,6 +86,112 @@ int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t >> > domid, >> > return 0; >> > } >> > +/* Decrease the refcount of an sshm. When refcount reaches 0, >> >> NIT: Libxl coding style regarding the comment seems to be uncleared (Ian, >> Wei?). But I feel keep /* and */ in separate line is nicer. > > I don't have an opinion here. > >> >> > + * clean up the whole sshm path. >> > + */ >> > +static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt, >> > + const char *sshm_path) >> > +static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt, >> > + uint32_t domid, const char *id, bool >> > isretry) >> > +{ >> > +const char *slave_path, *begin_str, *end_str; >> > +uint64_t begin, end; >> > + >> > +slave_path = GCSPRINTF("%s/slaves/%"PRIu32, SSHM_PATH(id), domid); >> > + >> > +begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", slave_path)); >> > +end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path)); >> > +begin = strtoull(begin_str, NULL, 16); >> > +end = strtoull(end_str, NULL, 16); >> > + >> > +/* Avoid calling do_unmap many times in case of xs transaction retry >> > */ >> > +if (!isretry) >> > +libxl__sshm_do_unmap(gc, domid, id, begin, end); >> >> IHMO, by unmapping the regions in middle of the transaction, you increase >> the potential failure of it. I would move that out of the transaction path. >> >> I would be interested to hear the opinion of the tools maintainers here. >> > > If you move the unmap after the loop you create a window in which > the pages are still mapped but the toolstack thinks they are unmapped. > > While the code as-is now makes sure (assuming no error in unmap) the > pages are unmapped no later than the transaction is committed. I think > this can be done by moving unmap before the transaction. > > Zhongze, do you think the unmap must be done inside the loop? What kind > of invariants do you have in mind? > > Then there is the question of "what do we do if unmap fails". Honestly I > don't have an answer. It seems rather screwed up in that case and I > doubt there is much libxl can do to rectify things. > I put the unmap inside the transaction because I want to make the whole read_mapping_info->unmap->update_mapping_info process atomic. If I put unmap outside the transaction: after I read out the information that I need to do the unmap, and before I do the unmap and decrease the refcnt, there could be another instance of this code trying to do the same thing, which might lead to race condition. And yes, I don't think we can do much in case of something go wrong, so what I'm doing here is just to do as best as I can -- unmapping all that pages that can be unmapped and cleanup the xs entries. Cheers, Zhongze Liu ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction
On Tue, Feb 06, 2018 at 01:24:30PM +, Julien Grall wrote: > > if (libxl__device_pci_destroy_all(gc, domid) < 0) > > LOGD(ERROR, domid, "Pci shutdown failed"); > > rc = xc_domain_pause(ctx->xch, domid); > > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > > index 2cfe4c08a7..c398b6a6b8 100644 > > --- a/tools/libxl/libxl_internal.h > > +++ b/tools/libxl/libxl_internal.h > > @@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char **s) > > _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid, > > libxl_static_shm *sshm, int len); > > +_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid); > > + > > _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, > > libxl_static_shm *sshms, int len); > > _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid, > > diff --git a/tools/libxl/libxl_sshm.c b/tools/libxl/libxl_sshm.c > > index 562f46f299..1bf4d4c2dc 100644 > > --- a/tools/libxl/libxl_sshm.c > > +++ b/tools/libxl/libxl_sshm.c > > @@ -86,6 +86,112 @@ int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t > > domid, > > return 0; > > } > > +/* Decrease the refcount of an sshm. When refcount reaches 0, > > NIT: Libxl coding style regarding the comment seems to be uncleared (Ian, > Wei?). But I feel keep /* and */ in separate line is nicer. I don't have an opinion here. > > > + * clean up the whole sshm path. > > + */ > > +static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt, > > + const char *sshm_path) > > +static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt, > > + uint32_t domid, const char *id, bool > > isretry) > > +{ > > +const char *slave_path, *begin_str, *end_str; > > +uint64_t begin, end; > > + > > +slave_path = GCSPRINTF("%s/slaves/%"PRIu32, SSHM_PATH(id), domid); > > + > > +begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", slave_path)); > > +end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path)); > > +begin = strtoull(begin_str, NULL, 16); > > +end = strtoull(end_str, NULL, 16); > > + > > +/* Avoid calling do_unmap many times in case of xs transaction retry */ > > +if (!isretry) > > +libxl__sshm_do_unmap(gc, domid, id, begin, end); > > IHMO, by unmapping the regions in middle of the transaction, you increase > the potential failure of it. I would move that out of the transaction path. > > I would be interested to hear the opinion of the tools maintainers here. > If you move the unmap after the loop you create a window in which the pages are still mapped but the toolstack thinks they are unmapped. While the code as-is now makes sure (assuming no error in unmap) the pages are unmapped no later than the transaction is committed. I think this can be done by moving unmap before the transaction. Zhongze, do you think the unmap must be done inside the loop? What kind of invariants do you have in mind? Then there is the question of "what do we do if unmap fails". Honestly I don't have an answer. It seems rather screwed up in that case and I doubt there is much libxl can do to rectify things. Wei. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction
Hi, On 01/30/2018 05:50 PM, Zhongze Liu wrote: Add libxl__sshm_del to unmap static shared memory areas mapped by libxl__sshm_add during domain creation. The unmapping process is: * For a master: decrease the refcount of the sshm region, if the refcount reaches 0, cleanup the whole sshm path. * For a slave: 1) unmap the shared pages, and cleanup related xs entries. If the system works normally, all the shared pages will be unmapped, so there won't be page leaks. In case of errors, the unmapping process will go on and unmap all the other pages that can be unmapped, so the other pages won't be leaked, either. 2) Decrease the refcount of the sshm region, if the refcount reaches 0, cleanup the whole sshm path. May I ask to add a newline line 1) and 2). This would make clearer the 2 steps. This is for the proposal "Allow setting up shared memory areas between VMs from xl config file" (see [1]). [1] https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html Signed-off-by: Zhongze LiuCc: Ian Jackson Cc: Wei Liu Cc: Stefano Stabellini Cc: Julien Grall Cc: xen-de...@lists.xen.org --- tools/libxl/libxl_domain.c | 5 ++ tools/libxl/libxl_internal.h | 2 + tools/libxl/libxl_sshm.c | 106 +++ 3 files changed, 113 insertions(+) diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c index 13b1c73d40..37f001554b 100644 --- a/tools/libxl/libxl_domain.c +++ b/tools/libxl/libxl_domain.c @@ -1026,6 +1026,11 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis) goto out; } +rc = libxl__sshm_del(gc, domid); +if (rc) { +LOGD(ERROR, domid, "Deleting static shm failed."); +} + if (libxl__device_pci_destroy_all(gc, domid) < 0) LOGD(ERROR, domid, "Pci shutdown failed"); rc = xc_domain_pause(ctx->xch, domid); diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 2cfe4c08a7..c398b6a6b8 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char **s) _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid, libxl_static_shm *sshm, int len); +_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid); + _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, libxl_static_shm *sshms, int len); _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid, diff --git a/tools/libxl/libxl_sshm.c b/tools/libxl/libxl_sshm.c index 562f46f299..1bf4d4c2dc 100644 --- a/tools/libxl/libxl_sshm.c +++ b/tools/libxl/libxl_sshm.c @@ -86,6 +86,112 @@ int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, return 0; } +/* Decrease the refcount of an sshm. When refcount reaches 0, NIT: Libxl coding style regarding the comment seems to be uncleared (Ian, Wei?). But I feel keep /* and */ in separate line is nicer. + * clean up the whole sshm path. + */ +static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt, + const char *sshm_path) +{ +int count; +const char *count_path, *count_string; + +count_path = GCSPRINTF("%s/usercnt", sshm_path); +if (libxl__xs_read_checked(gc, xt, count_path, _string)) +return; +count = atoi(count_string); + +if (--count == 0) { +libxl__xs_path_cleanup(gc, xt, sshm_path); +return; +} + +count_string = GCSPRINTF("%d", count); +libxl__xs_write_checked(gc, xt, count_path, count_string); See my comment about incref in a patch #4. + +return; +} + +static void libxl__sshm_do_unmap(libxl__gc *gc, uint32_t domid, const char *id, + uint64_t begin, uint64_t end) +{ +begin >>= XC_PAGE_SHIFT; +end >>= XC_PAGE_SHIFT; +for (; begin < end; ++begin) { +if (xc_domain_remove_from_physmap(CTX->xch, domid, begin)) { +SSHM_ERROR(domid, id, + "unable to unmap shared page at 0x%"PRIx64".", + begin); +} +} +} + +static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt, + uint32_t domid, const char *id, bool isretry) +{ +const char *slave_path, *begin_str, *end_str; +uint64_t begin, end; + +slave_path = GCSPRINTF("%s/slaves/%"PRIu32, SSHM_PATH(id), domid); + +begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", slave_path)); +end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path)); +begin = strtoull(begin_str, NULL, 16); +end = strtoull(end_str, NULL, 16); + +/* Avoid calling do_unmap many times in case of xs transaction retry */ +if (!isretry) +libxl__sshm_do_unmap(gc, domid, id, begin,