Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'edac_for_3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp

Pull EDAC fixes from Borislav Petkov:
"Fix polling timeout setting through sysfs.

You're surely wondering why the patches are not based on an rc. Well,
Andrew sent you 79040cad3f82 ("drivers/edac/edac_mc_sysfs.c: poll
timeout cannot be zero sent you") already (it got in in -rc2) but it
is not enough as a fix because for one, setting too low polling
intervals (< 1sec) don't make any sense and cause unnecessary polling
load on the system.

Then, even if we set some interval, we explode with

[ 4143.094342] WARNING: CPU: 1 PID: 0 at kernel/workqueue.c:1393 __queue_work+0x1d7/0x340()

because the workqueue setup path is used also for the timeout period
resetting and we're doing INIT_DELAYED_WORK() on an already active
workqueue. Which is total bollocks. So this is taken care of by the
second patch.

I've CCed stable for those two"

* tag 'edac_for_3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp:
EDAC: Correct workqueue setup path
EDAC: Poll timeout cannot be zero, p2

+15 -10
+8 -5
drivers/edac/edac_mc.c
··· 559 559 * 560 560 * called with the mem_ctls_mutex held 561 561 */ 562 - static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec) 562 + static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec, 563 + bool init) 563 564 { 564 565 edac_dbg(0, "\n"); 565 566 ··· 568 567 if (mci->op_state != OP_RUNNING_POLL) 569 568 return; 570 569 571 - INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function); 570 + if (init) 571 + INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function); 572 + 572 573 mod_delayed_work(edac_workqueue, &mci->work, msecs_to_jiffies(msec)); 573 574 } 574 575 ··· 604 601 * user space has updated our poll period value, need to 605 602 * reset our workq delays 606 603 */ 607 - void edac_mc_reset_delay_period(int value) 604 + void edac_mc_reset_delay_period(unsigned long value) 608 605 { 609 606 struct mem_ctl_info *mci; 610 607 struct list_head *item; ··· 614 611 list_for_each(item, &mc_devices) { 615 612 mci = list_entry(item, struct mem_ctl_info, link); 616 613 617 - edac_mc_workq_setup(mci, (unsigned long) value); 614 + edac_mc_workq_setup(mci, value, false); 618 615 } 619 616 620 617 mutex_unlock(&mem_ctls_mutex); ··· 785 782 /* This instance is NOW RUNNING */ 786 783 mci->op_state = OP_RUNNING_POLL; 787 784 788 - edac_mc_workq_setup(mci, edac_mc_get_poll_msec()); 785 + edac_mc_workq_setup(mci, edac_mc_get_poll_msec(), true); 789 786 } else { 790 787 mci->op_state = OP_RUNNING_INTERRUPT; 791 788 }
+6 -4
drivers/edac/edac_mc_sysfs.c
··· 52 52 53 53 static int edac_set_poll_msec(const char *val, struct kernel_param *kp) 54 54 { 55 - long l; 55 + unsigned long l; 56 56 int ret; 57 57 58 58 if (!val) 59 59 return -EINVAL; 60 60 61 - ret = kstrtol(val, 0, &l); 61 + ret = kstrtoul(val, 0, &l); 62 62 if (ret) 63 63 return ret; 64 - if (!l || ((int)l != l)) 64 + 65 + if (l < 1000) 65 66 return -EINVAL; 66 - *((int *)kp->arg) = l; 67 + 68 + *((unsigned long *)kp->arg) = l; 67 69 68 70 /* notify edac_mc engine to reset the poll period */ 69 71 edac_mc_reset_delay_period(l);
+1 -1
drivers/edac/edac_module.h
··· 52 52 extern void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev); 53 53 extern void edac_device_reset_delay_period(struct edac_device_ctl_info 54 54 *edac_dev, unsigned long value); 55 - extern void edac_mc_reset_delay_period(int value); 55 + extern void edac_mc_reset_delay_period(unsigned long value); 56 56 57 57 extern void *edac_align_ptr(void **p, unsigned size, int n_elems); 58 58