.. | .. |
---|
34 | 34 | static DEFINE_MUTEX(device_ctls_mutex); |
---|
35 | 35 | static LIST_HEAD(edac_device_list); |
---|
36 | 36 | |
---|
| 37 | +/* Default workqueue processing interval on this instance, in msecs */ |
---|
| 38 | +#define DEFAULT_POLL_INTERVAL 1000 |
---|
| 39 | + |
---|
37 | 40 | #ifdef CONFIG_EDAC_DEBUG |
---|
38 | 41 | static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev) |
---|
39 | 42 | { |
---|
.. | .. |
---|
366 | 369 | * whole one second to save timers firing all over the period |
---|
367 | 370 | * between integral seconds |
---|
368 | 371 | */ |
---|
369 | | - if (edac_dev->poll_msec == 1000) |
---|
| 372 | + if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL) |
---|
370 | 373 | edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay)); |
---|
371 | 374 | else |
---|
372 | 375 | edac_queue_work(&edac_dev->work, edac_dev->delay); |
---|
.. | .. |
---|
396 | 399 | * timers firing on sub-second basis, while they are happy |
---|
397 | 400 | * to fire together on the 1 second exactly |
---|
398 | 401 | */ |
---|
399 | | - if (edac_dev->poll_msec == 1000) |
---|
| 402 | + if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL) |
---|
400 | 403 | edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay)); |
---|
401 | 404 | else |
---|
402 | 405 | edac_queue_work(&edac_dev->work, edac_dev->delay); |
---|
.. | .. |
---|
424 | 427 | * Then restart the workq on the new delay |
---|
425 | 428 | */ |
---|
426 | 429 | void edac_device_reset_delay_period(struct edac_device_ctl_info *edac_dev, |
---|
427 | | - unsigned long value) |
---|
| 430 | + unsigned long msec) |
---|
428 | 431 | { |
---|
429 | | - unsigned long jiffs = msecs_to_jiffies(value); |
---|
| 432 | + edac_dev->poll_msec = msec; |
---|
| 433 | + edac_dev->delay = msecs_to_jiffies(msec); |
---|
430 | 434 | |
---|
431 | | - if (value == 1000) |
---|
432 | | - jiffs = round_jiffies_relative(value); |
---|
433 | | - |
---|
434 | | - edac_dev->poll_msec = value; |
---|
435 | | - edac_dev->delay = jiffs; |
---|
436 | | - |
---|
437 | | - edac_mod_work(&edac_dev->work, jiffs); |
---|
| 435 | + /* See comment in edac_device_workq_setup() above */ |
---|
| 436 | + if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL) |
---|
| 437 | + edac_mod_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay)); |
---|
| 438 | + else |
---|
| 439 | + edac_mod_work(&edac_dev->work, edac_dev->delay); |
---|
438 | 440 | } |
---|
439 | 441 | |
---|
440 | 442 | int edac_device_alloc_index(void) |
---|
.. | .. |
---|
473 | 475 | /* This instance is NOW RUNNING */ |
---|
474 | 476 | edac_dev->op_state = OP_RUNNING_POLL; |
---|
475 | 477 | |
---|
476 | | - /* |
---|
477 | | - * enable workq processing on this instance, |
---|
478 | | - * default = 1000 msec |
---|
479 | | - */ |
---|
480 | | - edac_device_workq_setup(edac_dev, 1000); |
---|
| 478 | + edac_device_workq_setup(edac_dev, edac_dev->poll_msec ?: DEFAULT_POLL_INTERVAL); |
---|
481 | 479 | } else { |
---|
482 | 480 | edac_dev->op_state = OP_RUNNING_INTERRUPT; |
---|
483 | 481 | } |
---|
.. | .. |
---|
555 | 553 | return edac_dev->panic_on_ue; |
---|
556 | 554 | } |
---|
557 | 555 | |
---|
558 | | -void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev, |
---|
559 | | - int inst_nr, int block_nr, const char *msg) |
---|
| 556 | +void edac_device_handle_ce_count(struct edac_device_ctl_info *edac_dev, |
---|
| 557 | + unsigned int count, int inst_nr, int block_nr, |
---|
| 558 | + const char *msg) |
---|
560 | 559 | { |
---|
561 | 560 | struct edac_device_instance *instance; |
---|
562 | 561 | struct edac_device_block *block = NULL; |
---|
| 562 | + |
---|
| 563 | + if (!count) |
---|
| 564 | + return; |
---|
563 | 565 | |
---|
564 | 566 | if ((inst_nr >= edac_dev->nr_instances) || (inst_nr < 0)) { |
---|
565 | 567 | edac_device_printk(edac_dev, KERN_ERR, |
---|
.. | .. |
---|
582 | 584 | |
---|
583 | 585 | if (instance->nr_blocks > 0) { |
---|
584 | 586 | block = instance->blocks + block_nr; |
---|
585 | | - block->counters.ce_count++; |
---|
| 587 | + block->counters.ce_count += count; |
---|
586 | 588 | } |
---|
587 | 589 | |
---|
588 | 590 | /* Propagate the count up the 'totals' tree */ |
---|
589 | | - instance->counters.ce_count++; |
---|
590 | | - edac_dev->counters.ce_count++; |
---|
| 591 | + instance->counters.ce_count += count; |
---|
| 592 | + edac_dev->counters.ce_count += count; |
---|
591 | 593 | |
---|
592 | 594 | if (edac_device_get_log_ce(edac_dev)) |
---|
593 | 595 | edac_device_printk(edac_dev, KERN_WARNING, |
---|
594 | | - "CE: %s instance: %s block: %s '%s'\n", |
---|
595 | | - edac_dev->ctl_name, instance->name, |
---|
596 | | - block ? block->name : "N/A", msg); |
---|
| 596 | + "CE: %s instance: %s block: %s count: %d '%s'\n", |
---|
| 597 | + edac_dev->ctl_name, instance->name, |
---|
| 598 | + block ? block->name : "N/A", count, msg); |
---|
597 | 599 | } |
---|
598 | | -EXPORT_SYMBOL_GPL(edac_device_handle_ce); |
---|
| 600 | +EXPORT_SYMBOL_GPL(edac_device_handle_ce_count); |
---|
599 | 601 | |
---|
600 | | -void edac_device_handle_ue(struct edac_device_ctl_info *edac_dev, |
---|
601 | | - int inst_nr, int block_nr, const char *msg) |
---|
| 602 | +void edac_device_handle_ue_count(struct edac_device_ctl_info *edac_dev, |
---|
| 603 | + unsigned int count, int inst_nr, int block_nr, |
---|
| 604 | + const char *msg) |
---|
602 | 605 | { |
---|
603 | 606 | struct edac_device_instance *instance; |
---|
604 | 607 | struct edac_device_block *block = NULL; |
---|
| 608 | + |
---|
| 609 | + if (!count) |
---|
| 610 | + return; |
---|
605 | 611 | |
---|
606 | 612 | if ((inst_nr >= edac_dev->nr_instances) || (inst_nr < 0)) { |
---|
607 | 613 | edac_device_printk(edac_dev, KERN_ERR, |
---|
.. | .. |
---|
624 | 630 | |
---|
625 | 631 | if (instance->nr_blocks > 0) { |
---|
626 | 632 | block = instance->blocks + block_nr; |
---|
627 | | - block->counters.ue_count++; |
---|
| 633 | + block->counters.ue_count += count; |
---|
628 | 634 | } |
---|
629 | 635 | |
---|
630 | 636 | /* Propagate the count up the 'totals' tree */ |
---|
631 | | - instance->counters.ue_count++; |
---|
632 | | - edac_dev->counters.ue_count++; |
---|
| 637 | + instance->counters.ue_count += count; |
---|
| 638 | + edac_dev->counters.ue_count += count; |
---|
633 | 639 | |
---|
634 | 640 | if (edac_device_get_log_ue(edac_dev)) |
---|
635 | 641 | edac_device_printk(edac_dev, KERN_EMERG, |
---|
636 | | - "UE: %s instance: %s block: %s '%s'\n", |
---|
637 | | - edac_dev->ctl_name, instance->name, |
---|
638 | | - block ? block->name : "N/A", msg); |
---|
| 642 | + "UE: %s instance: %s block: %s count: %d '%s'\n", |
---|
| 643 | + edac_dev->ctl_name, instance->name, |
---|
| 644 | + block ? block->name : "N/A", count, msg); |
---|
639 | 645 | |
---|
640 | 646 | if (edac_device_get_panic_on_ue(edac_dev)) |
---|
641 | | - panic("EDAC %s: UE instance: %s block %s '%s'\n", |
---|
642 | | - edac_dev->ctl_name, instance->name, |
---|
643 | | - block ? block->name : "N/A", msg); |
---|
| 647 | + panic("EDAC %s: UE instance: %s block %s count: %d '%s'\n", |
---|
| 648 | + edac_dev->ctl_name, instance->name, |
---|
| 649 | + block ? block->name : "N/A", count, msg); |
---|
644 | 650 | } |
---|
645 | | -EXPORT_SYMBOL_GPL(edac_device_handle_ue); |
---|
| 651 | +EXPORT_SYMBOL_GPL(edac_device_handle_ue_count); |
---|