diff options
author | David Vrabel <david.vrabel@citrix.com> | 2015-08-10 13:11:06 -0400 |
---|---|---|
committer | David Vrabel <david.vrabel@citrix.com> | 2015-08-11 06:05:42 -0400 |
commit | ad6cd7bafcd2c812ba4200d5938e07304f1e2fcd (patch) | |
tree | 2e95f2da6be2370391321941895528e915ad5e26 /drivers | |
parent | fc5fee86bdd3d720e2d1d324e4fae0c35845fa63 (diff) |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/xen/events/events_base.c | 10 | ||||
-rw-r--r-- | drivers/xen/events/events_fifo.c | 45 | ||||
-rw-r--r-- | drivers/xen/events/events_internal.h | 7 |
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 | ||
455 | static void xen_evtchn_close(unsigned int port, unsigned int cpu) | 455 | static 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 | ||
547 | err: | 545 | err: |
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 | ||
258 | static 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 | |||
264 | static uint32_t clear_linked(volatile event_word_t *word) | 258 | static 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 | ||
288 | static void consume_one_event(unsigned cpu, | 282 | static 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 | ||
331 | static void __evtchn_fifo_handle_events(unsigned cpu, bool drop) | 322 | static 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 | ||
348 | static void evtchn_fifo_handle_events(unsigned cpu) | ||
349 | { | ||
350 | __evtchn_fifo_handle_events(cpu, false); | ||
351 | } | ||
352 | |||
353 | static void evtchn_fifo_resume(void) | 339 | static 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 | ||
388 | static 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 | |||
404 | out: | ||
405 | put_online_cpus(); | ||
406 | } | ||
407 | |||
408 | static const struct evtchn_ops evtchn_ops_fifo = { | 374 | static 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 | ||
424 | static int evtchn_fifo_alloc_control_block(unsigned cpu) | 389 | static 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 | ||
149 | static 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 | |||
155 | void xen_evtchn_2l_init(void); | 148 | void xen_evtchn_2l_init(void); |
156 | int xen_evtchn_fifo_init(void); | 149 | int xen_evtchn_fifo_init(void); |
157 | 150 | ||