From mboxrd@z Thu Jan 1 00:00:00 1970 From: Boris Ostrovsky Subject: Re: [PATCH] xen/events/fifo: Consume unprocessed events when a CPU dies Date: Fri, 19 Jun 2015 12:02:36 -0400 Message-ID: <55843D1C.9070905@oracle.com> References: <1434726957-929-1-git-send-email-ross.lagerwall@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1Z5yko-0006vc-PI for xen-devel@lists.xenproject.org; Fri, 19 Jun 2015 16:02:54 +0000 In-Reply-To: <1434726957-929-1-git-send-email-ross.lagerwall@citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Ross Lagerwall , xen-devel@lists.xenproject.org Cc: David Vrabel List-Id: xen-devel@lists.xenproject.org On 06/19/2015 11:15 AM, Ross Lagerwall wrote: > When a CPU is offlined, there may be unprocessed events on a port for > that CPU. If the port is subsequently reused on a different CPU, it > could be in an unexpected state with the link bit set, resulting in > interrupts being missed. Fix this by consuming any unprocessed events > for a particular CPU when that CPU dies. > > Signed-off-by: Ross Lagerwall > --- > drivers/xen/events/events_fifo.c | 23 ++++++++++++++++++----- > 1 file changed, 18 insertions(+), 5 deletions(-) > > diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c > index 417415d..1dd0ba12 100644 > --- a/drivers/xen/events/events_fifo.c > +++ b/drivers/xen/events/events_fifo.c > @@ -281,7 +281,8 @@ static void handle_irq_for_port(unsigned port) > > static void consume_one_event(unsigned cpu, > struct evtchn_fifo_control_block *control_block, > - unsigned priority, unsigned long *ready) > + unsigned priority, unsigned long *ready, > + bool drop) > { > struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu); > uint32_t head; > @@ -313,13 +314,17 @@ static void consume_one_event(unsigned cpu, > if (head == 0) > clear_bit(priority, ready); > > - if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port)) > - handle_irq_for_port(port); > + if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port)) { > + if (unlikely(drop)) > + pr_warn("Dropping pending event for port %u\n", port); Maybe pr_info (or pr_notice)? Also, why not do this (testing for unprocessed events) in xen_evtchn_close()? -boris > + else > + handle_irq_for_port(port); > + } > > q->head[priority] = head; > } > > -static void evtchn_fifo_handle_events(unsigned cpu) > +static void __evtchn_fifo_handle_events(unsigned cpu, bool drop) > { > struct evtchn_fifo_control_block *control_block; > unsigned long ready; > @@ -331,11 +336,16 @@ static void evtchn_fifo_handle_events(unsigned cpu) > > while (ready) { > q = find_first_bit(&ready, EVTCHN_FIFO_MAX_QUEUES); > - consume_one_event(cpu, control_block, q, &ready); > + consume_one_event(cpu, control_block, q, &ready, drop); > ready |= xchg(&control_block->ready, 0); > } > } > > +static void evtchn_fifo_handle_events(unsigned cpu) > +{ > + __evtchn_fifo_handle_events(cpu, false); > +} > + > static void evtchn_fifo_resume(void) > { > unsigned cpu; > @@ -420,6 +430,9 @@ static int evtchn_fifo_cpu_notification(struct notifier_block *self, > if (!per_cpu(cpu_control_block, cpu)) > ret = evtchn_fifo_alloc_control_block(cpu); > break; > + case CPU_DEAD: > + __evtchn_fifo_handle_events(cpu, true); > + break; > default: > break; > }