aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Vrabel2015-08-10 12:11:06 -0500
committerDavid Vrabel2015-08-11 05:05:42 -0500
commitad6cd7bafcd2c812ba4200d5938e07304f1e2fcd (patch)
tree2e95f2da6be2370391321941895528e915ad5e26
parentfc5fee86bdd3d720e2d1d324e4fae0c35845fa63 (diff)
downloadafd-analog-ad6cd7bafcd2c812ba4200d5938e07304f1e2fcd.tar.gz
afd-analog-ad6cd7bafcd2c812ba4200d5938e07304f1e2fcd.tar.xz
afd-analog-ad6cd7bafcd2c812ba4200d5938e07304f1e2fcd.zip
Revert "xen/events/fifo: Handle linked events when closing a port"
This reverts commit fcdf31a7c162de0c93a2bee51df4688ab0a348f8. This was causing a WARNING whenever a PIRQ was closed since shutdown_pirq() is called with irqs disabled. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Cc: <stable@vger.kernel.org>
-rw-r--r--drivers/xen/events/events_base.c10
-rw-r--r--drivers/xen/events/events_fifo.c45
-rw-r--r--drivers/xen/events/events_internal.h7
3 files changed, 9 insertions, 53 deletions
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 1495eccb1617..96093ae369a5 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -452,12 +452,10 @@ static void xen_free_irq(unsigned irq)
452 irq_free_desc(irq); 452 irq_free_desc(irq);
453} 453}
454 454
455static void xen_evtchn_close(unsigned int port, unsigned int cpu) 455static void xen_evtchn_close(unsigned int port)
456{ 456{
457 struct evtchn_close close; 457 struct evtchn_close close;
458 458
459 xen_evtchn_op_close(port, cpu);
460
461 close.port = port; 459 close.port = port;
462 if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0) 460 if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
463 BUG(); 461 BUG();
@@ -546,7 +544,7 @@ out:
546 544
547err: 545err:
548 pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc); 546 pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc);
549 xen_evtchn_close(evtchn, NR_CPUS); 547 xen_evtchn_close(evtchn);
550 return 0; 548 return 0;
551} 549}
552 550
@@ -567,7 +565,7 @@ static void shutdown_pirq(struct irq_data *data)
567 return; 565 return;
568 566
569 mask_evtchn(evtchn); 567 mask_evtchn(evtchn);
570 xen_evtchn_close(evtchn, cpu_from_evtchn(evtchn)); 568 xen_evtchn_close(evtchn);
571 xen_irq_info_cleanup(info); 569 xen_irq_info_cleanup(info);
572} 570}
573 571
@@ -611,7 +609,7 @@ static void __unbind_from_irq(unsigned int irq)
611 if (VALID_EVTCHN(evtchn)) { 609 if (VALID_EVTCHN(evtchn)) {
612 unsigned int cpu = cpu_from_irq(irq); 610 unsigned int cpu = cpu_from_irq(irq);
613 611
614 xen_evtchn_close(evtchn, cpu); 612 xen_evtchn_close(evtchn);
615 613
616 switch (type_from_irq(irq)) { 614 switch (type_from_irq(irq)) {
617 case IRQT_VIRQ: 615 case IRQT_VIRQ:
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index 6df8aac966b9..ed673e1acd61 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -255,12 +255,6 @@ static void evtchn_fifo_unmask(unsigned port)
255 } 255 }
256} 256}
257 257
258static bool evtchn_fifo_is_linked(unsigned port)
259{
260 event_word_t *word = event_word_from_port(port);
261 return sync_test_bit(EVTCHN_FIFO_BIT(LINKED, word), BM(word));
262}
263
264static uint32_t clear_linked(volatile event_word_t *word) 258static uint32_t clear_linked(volatile event_word_t *word)
265{ 259{
266 event_word_t new, old, w; 260 event_word_t new, old, w;
@@ -287,8 +281,7 @@ static void handle_irq_for_port(unsigned port)
287 281
288static void consume_one_event(unsigned cpu, 282static void consume_one_event(unsigned cpu,
289 struct evtchn_fifo_control_block *control_block, 283 struct evtchn_fifo_control_block *control_block,
290 unsigned priority, unsigned long *ready, 284 unsigned priority, unsigned long *ready)
291 bool drop)
292{ 285{
293 struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu); 286 struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu);
294 uint32_t head; 287 uint32_t head;
@@ -320,15 +313,13 @@ static void consume_one_event(unsigned cpu,
320 if (head == 0) 313 if (head == 0)
321 clear_bit(priority, ready); 314 clear_bit(priority, ready);
322 315
323 if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port)) { 316 if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port))
324 if (likely(!drop)) 317 handle_irq_for_port(port);
325 handle_irq_for_port(port);
326 }
327 318
328 q->head[priority] = head; 319 q->head[priority] = head;
329} 320}
330 321
331static void __evtchn_fifo_handle_events(unsigned cpu, bool drop) 322static void evtchn_fifo_handle_events(unsigned cpu)
332{ 323{
333 struct evtchn_fifo_control_block *control_block; 324 struct evtchn_fifo_control_block *control_block;
334 unsigned long ready; 325 unsigned long ready;
@@ -340,16 +331,11 @@ static void __evtchn_fifo_handle_events(unsigned cpu, bool drop)
340 331
341 while (ready) { 332 while (ready) {
342 q = find_first_bit(&ready, EVTCHN_FIFO_MAX_QUEUES); 333 q = find_first_bit(&ready, EVTCHN_FIFO_MAX_QUEUES);
343 consume_one_event(cpu, control_block, q, &ready, drop); 334 consume_one_event(cpu, control_block, q, &ready);
344 ready |= xchg(&control_block->ready, 0); 335 ready |= xchg(&control_block->ready, 0);
345 } 336 }
346} 337}
347 338
348static void evtchn_fifo_handle_events(unsigned cpu)
349{
350 __evtchn_fifo_handle_events(cpu, false);
351}
352
353static void evtchn_fifo_resume(void) 339static void evtchn_fifo_resume(void)
354{ 340{
355 unsigned cpu; 341 unsigned cpu;
@@ -385,26 +371,6 @@ static void evtchn_fifo_resume(void)
385 event_array_pages = 0; 371 event_array_pages = 0;
386} 372}
387 373
388static void evtchn_fifo_close(unsigned port, unsigned int cpu)
389{
390 if (cpu == NR_CPUS)
391 return;
392
393 get_online_cpus();
394 if (cpu_online(cpu)) {
395 if (WARN_ON(irqs_disabled()))
396 goto out;
397
398 while (evtchn_fifo_is_linked(port))
399 cpu_relax();
400 } else {
401 __evtchn_fifo_handle_events(cpu, true);
402 }
403
404out:
405 put_online_cpus();
406}
407
408static const struct evtchn_ops evtchn_ops_fifo = { 374static const struct evtchn_ops evtchn_ops_fifo = {
409 .max_channels = evtchn_fifo_max_channels, 375 .max_channels = evtchn_fifo_max_channels,
410 .nr_channels = evtchn_fifo_nr_channels, 376 .nr_channels = evtchn_fifo_nr_channels,
@@ -418,7 +384,6 @@ static const struct evtchn_ops evtchn_ops_fifo = {
418 .unmask = evtchn_fifo_unmask, 384 .unmask = evtchn_fifo_unmask,
419 .handle_events = evtchn_fifo_handle_events, 385 .handle_events = evtchn_fifo_handle_events,
420 .resume = evtchn_fifo_resume, 386 .resume = evtchn_fifo_resume,
421 .close = evtchn_fifo_close,
422}; 387};
423 388
424static int evtchn_fifo_alloc_control_block(unsigned cpu) 389static int evtchn_fifo_alloc_control_block(unsigned cpu)
diff --git a/drivers/xen/events/events_internal.h b/drivers/xen/events/events_internal.h
index d18e12315ec0..50c2050a1e32 100644
--- a/drivers/xen/events/events_internal.h
+++ b/drivers/xen/events/events_internal.h
@@ -68,7 +68,6 @@ struct evtchn_ops {
68 bool (*test_and_set_mask)(unsigned port); 68 bool (*test_and_set_mask)(unsigned port);
69 void (*mask)(unsigned port); 69 void (*mask)(unsigned port);
70 void (*unmask)(unsigned port); 70 void (*unmask)(unsigned port);
71 void (*close)(unsigned port, unsigned cpu);
72 71
73 void (*handle_events)(unsigned cpu); 72 void (*handle_events)(unsigned cpu);
74 void (*resume)(void); 73 void (*resume)(void);
@@ -146,12 +145,6 @@ static inline void xen_evtchn_resume(void)
146 evtchn_ops->resume(); 145 evtchn_ops->resume();
147} 146}
148 147
149static inline void xen_evtchn_op_close(unsigned port, unsigned cpu)
150{
151 if (evtchn_ops->close)
152 return evtchn_ops->close(port, cpu);
153}
154
155void xen_evtchn_2l_init(void); 148void xen_evtchn_2l_init(void);
156int xen_evtchn_fifo_init(void); 149int xen_evtchn_fifo_init(void);
157 150