|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] xen/common: Properly reference count DOMCTL_{, un}pausedomain hypercalls
On 07/01/14 15:57, Andrew Cooper wrote:
> For safety reasons, c/s 6ae2df93c27 "mem_access: Add helper API to setup
> ring and enable mem_access" has to pause the domain while it performs a set of
> operations.
>
> However without properly reference counted hypercalls, xc_mem_event_enable()
> now unconditionally unpauses a previously paused domain.
>
> To prevent toolstack software running wild, there is an arbitrary limit of 255
> on the toolstack pause count. This is high enough for several components of
> the toolstack to safely use, but prevents over/underflow of d->pause_count.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> CC: Keir Fraser <keir@xxxxxxx>
> CC: Jan Beulich <JBeulich@xxxxxxxx>
> CC: Ian Campbell <ian.campbell@xxxxxxxxxx>
> CC: Stefano Stabellini <stefano.stabellini@xxxxxxxxxx>
> CC: Tim Deegan <tim@xxxxxxx>
>
> ---
>
> This has been functionally tested on x86, and compile tested on both flavours
> of ARM.
>
> Personally I dislike the addition of the spinlock, but I can't find a safe way
> of preventing over/underflow of d->pause_count with an atomic_t
> toolstack_pause_count alone. At least they are fine-grained locks and
> unlikely to be contended in practice.
atomic_cmpxchg() can be used to safely preventing over/underflow.
For example:
int safe_atomic_inc(int * intp)
{
int prev, old, new;
prev = atomic_read(*intp);
do {
old = prev;
new = old + 1;
if ( new > 255 )
return 1;
prev = atomic_cmpxchg(intp, old, new);
} while ( prev != old );
return 0;
}
int safe_atomic_dec(int * intp)
{
int prev, old, new;
prev = atomic_read(*intp);
do {
old = prev;
new = old - 1;
if ( new < 0 )
return 1;
prev = atomic_cmpxchg(intp, old, new);
} while ( prev != old );
return 0;
}
does what you are asking about (adjusted for correct types). Here is
a quick c prog using them:
#include <stdio.h>
#define atomic_read(x) x
#define atomic_cmpxchg __sync_val_compare_and_swap
int safe_atomic_inc(int * intp)
{
int prev, old, new;
prev = atomic_read(*intp);
do {
old = prev;
new = old + 1;
if ( new > 255 )
return 1;
prev = atomic_cmpxchg(intp, old, new);
} while ( prev != old );
return 0;
}
int safe_atomic_dec(int * intp)
{
int prev, old, new;
prev = atomic_read(*intp);
do {
old = prev;
new = old - 1;
if ( new < 0 )
return 1;
prev = atomic_cmpxchg(intp, old, new);
} while ( prev != old );
return 0;
}
int
main(void)
{
int foo = 0;
int rc;
printf("foo=%d\n", foo);
rc = safe_atomic_dec(&foo);
printf("rc=%d foo--=%d\n", rc, foo);
rc = safe_atomic_inc(&foo);
printf("rc=%d foo++=%d\n", rc, foo);
foo = 253;
printf("foo=%d\n", foo);
rc = safe_atomic_dec(&foo);
printf("rc=%d foo--=%d\n", rc, foo);
rc = safe_atomic_inc(&foo);
printf("rc=%d foo++=%d\n", rc, foo);
rc = safe_atomic_inc(&foo);
printf("rc=%d foo++=%d\n", rc, foo);
rc = safe_atomic_inc(&foo);
printf("rc=%d foo++=%d\n", rc, foo);
rc = safe_atomic_inc(&foo);
printf("rc=%d foo++=%d\n", rc, foo);
return rc;
}
-Don Slutz
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |