[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] RE: [PATCH v2 1/2] xen/events: access last_priority and last_vcpu_id together
> -----Original Message----- > From: Xen-devel <xen-devel-bounces@xxxxxxxxxxxxxxxxxxxx> On Behalf Of Juergen > Gross > Sent: 12 October 2020 10:28 > To: xen-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Juergen Gross <jgross@xxxxxxxx>; Andrew Cooper > <andrew.cooper3@xxxxxxxxxx>; George Dunlap > <george.dunlap@xxxxxxxxxx>; Ian Jackson <iwj@xxxxxxxxxxxxxx>; Jan Beulich > <jbeulich@xxxxxxxx>; Julien > Grall <julien@xxxxxxx>; Stefano Stabellini <sstabellini@xxxxxxxxxx>; Wei Liu > <wl@xxxxxxx> > Subject: [PATCH v2 1/2] xen/events: access last_priority and last_vcpu_id > together > > The queue for a fifo event is depending on the vcpu_id and the > priority of the event. When sending an event it might happen the > event needs to change queues and the old queue needs to be kept for > keeping the links between queue elements intact. For this purpose > the event channel contains last_priority and last_vcpu_id values > elements for being able to identify the old queue. > > In order to avoid races always access last_priority and last_vcpu_id > with a single atomic operation avoiding any inconsistencies. > > Signed-off-by: Juergen Gross <jgross@xxxxxxxx> > --- > xen/common/event_fifo.c | 25 +++++++++++++++++++------ > xen/include/xen/sched.h | 3 +-- > 2 files changed, 20 insertions(+), 8 deletions(-) > > diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c > index fc189152e1..fffbd409c8 100644 > --- a/xen/common/event_fifo.c > +++ b/xen/common/event_fifo.c > @@ -42,6 +42,14 @@ struct evtchn_fifo_domain { > unsigned int num_evtchns; > }; > > +union evtchn_fifo_lastq { > + u32 raw; > + struct { > + u8 last_priority; > + u16 last_vcpu_id; > + }; > +}; I guess you want to s/u32/uint32_t, etc. above. > + > static inline event_word_t *evtchn_fifo_word_from_port(const struct domain > *d, > unsigned int port) > { > @@ -86,16 +94,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const > struct domain *d, > struct vcpu *v; > struct evtchn_fifo_queue *q, *old_q; > unsigned int try; > + union evtchn_fifo_lastq lastq; > > for ( try = 0; try < 3; try++ ) > { > - v = d->vcpu[evtchn->last_vcpu_id]; > - old_q = &v->evtchn_fifo->queue[evtchn->last_priority]; > + lastq.raw = read_atomic(&evtchn->fifo_lastq); > + v = d->vcpu[lastq.last_vcpu_id]; > + old_q = &v->evtchn_fifo->queue[lastq.last_priority]; > > spin_lock_irqsave(&old_q->lock, *flags); > > - v = d->vcpu[evtchn->last_vcpu_id]; > - q = &v->evtchn_fifo->queue[evtchn->last_priority]; > + v = d->vcpu[lastq.last_vcpu_id]; > + q = &v->evtchn_fifo->queue[lastq.last_priority]; > > if ( old_q == q ) > return old_q; > @@ -246,8 +256,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, > struct evtchn *evtchn) > /* Moved to a different queue? */ > if ( old_q != q ) > { > - evtchn->last_vcpu_id = v->vcpu_id; > - evtchn->last_priority = q->priority; > + union evtchn_fifo_lastq lastq; > + > + lastq.last_vcpu_id = v->vcpu_id; > + lastq.last_priority = q->priority; > + write_atomic(&evtchn->fifo_lastq, lastq.raw); > You're going to leak some stack here I think. Perhaps add a 'pad' field between 'last_priority' and 'last_vcpu_id' and zero it? Paul > spin_unlock_irqrestore(&old_q->lock, flags); > spin_lock_irqsave(&q->lock, flags); > diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h > index d8ed83f869..a298ff4df8 100644 > --- a/xen/include/xen/sched.h > +++ b/xen/include/xen/sched.h > @@ -114,8 +114,7 @@ struct evtchn > u16 virq; /* state == ECS_VIRQ */ > } u; > u8 priority; > - u8 last_priority; > - u16 last_vcpu_id; > + u32 fifo_lastq; /* Data for fifo events identifying last queue. */ > #ifdef CONFIG_XSM > union { > #ifdef XSM_NEED_GENERIC_EVTCHN_SSID > -- > 2.26.2 >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |