aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Camuso <tcamuso@redhat.com>2017-04-10 12:22:13 -0400
committerCorey Minyard <cminyard@mvista.com>2017-04-10 13:42:10 -0400
commit3f724c408a7bcf25609f6a0102b835d5970cadd3 (patch)
tree018a97b7d1f977fe65204c4780181a0089bb5111
parent7ecaff7733b50da8e02d22be6719069892633c53 (diff)
ipmi_si: use smi_num for init_name
Commit 1abf71e moved the creation of new_smi->dev to earlier in the init sequence in order to provide infrastructure for log printing. However, the init_name was created with a hard-coded value of zero. This presents a problem in systems with more than one interface, producing a call trace in dmesg. To correct the problem, simply use smi_num instead of the hard-coded value of zero. Tested on a lenovo x3950. Signed-off-by: Tony Camuso <tcamuso@redhat.com> There was actually a more general problem, the platform device wasn't being set correctly, either, and there was a possible (though extremely unlikely) race on smi_num. Add locks to clean up the race and use the proper value for the platform device, too. Tested on qemu in various configurations. Signed-off-by: Corey Minyard <cminyard@mvista.com>
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 2a7c425ddfa7..b2b618f066e0 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1954,7 +1954,9 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
1954 kfree(info); 1954 kfree(info);
1955 goto out; 1955 goto out;
1956 } 1956 }
1957 mutex_lock(&smi_infos_lock);
1957 rv = try_smi_init(info); 1958 rv = try_smi_init(info);
1959 mutex_unlock(&smi_infos_lock);
1958 if (rv) { 1960 if (rv) {
1959 cleanup_one_si(info); 1961 cleanup_one_si(info);
1960 goto out; 1962 goto out;
@@ -2042,8 +2044,10 @@ static int hardcode_find_bmc(void)
2042 info->slave_addr = slave_addrs[i]; 2044 info->slave_addr = slave_addrs[i];
2043 2045
2044 if (!add_smi(info)) { 2046 if (!add_smi(info)) {
2047 mutex_lock(&smi_infos_lock);
2045 if (try_smi_init(info)) 2048 if (try_smi_init(info))
2046 cleanup_one_si(info); 2049 cleanup_one_si(info);
2050 mutex_unlock(&smi_infos_lock);
2047 ret = 0; 2051 ret = 0;
2048 } else { 2052 } else {
2049 kfree(info); 2053 kfree(info);
@@ -3492,6 +3496,11 @@ out_err:
3492 return rv; 3496 return rv;
3493} 3497}
3494 3498
3499/*
3500 * Try to start up an interface. Must be called with smi_infos_lock
3501 * held, primarily to keep smi_num consistent, we only one to do these
3502 * one at a time.
3503 */
3495static int try_smi_init(struct smi_info *new_smi) 3504static int try_smi_init(struct smi_info *new_smi)
3496{ 3505{
3497 int rv = 0; 3506 int rv = 0;
@@ -3524,9 +3533,12 @@ static int try_smi_init(struct smi_info *new_smi)
3524 goto out_err; 3533 goto out_err;
3525 } 3534 }
3526 3535
3536 new_smi->intf_num = smi_num;
3537
3527 /* Do this early so it's available for logs. */ 3538 /* Do this early so it's available for logs. */
3528 if (!new_smi->dev) { 3539 if (!new_smi->dev) {
3529 init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d", 0); 3540 init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d",
3541 new_smi->intf_num);
3530 3542
3531 /* 3543 /*
3532 * If we don't already have a device from something 3544 * If we don't already have a device from something
@@ -3593,8 +3605,6 @@ static int try_smi_init(struct smi_info *new_smi)
3593 3605
3594 new_smi->interrupt_disabled = true; 3606 new_smi->interrupt_disabled = true;
3595 atomic_set(&new_smi->need_watch, 0); 3607 atomic_set(&new_smi->need_watch, 0);
3596 new_smi->intf_num = smi_num;
3597 smi_num++;
3598 3608
3599 rv = try_enable_event_buffer(new_smi); 3609 rv = try_enable_event_buffer(new_smi);
3600 if (rv == 0) 3610 if (rv == 0)
@@ -3661,6 +3671,9 @@ static int try_smi_init(struct smi_info *new_smi)
3661 goto out_err_stop_timer; 3671 goto out_err_stop_timer;
3662 } 3672 }
3663 3673
3674 /* Don't increment till we know we have succeeded. */
3675 smi_num++;
3676
3664 dev_info(new_smi->dev, "IPMI %s interface initialized\n", 3677 dev_info(new_smi->dev, "IPMI %s interface initialized\n",
3665 si_to_str[new_smi->si_type]); 3678 si_to_str[new_smi->si_type]);
3666 3679