diff options
| -rw-r--r-- | drivers/char/ipmi/ipmi_dmi.c | 1 | ||||
| -rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 19 | ||||
| -rw-r--r-- | drivers/char/ipmi/ipmi_si_hardcode.c | 2 | 
3 files changed, 19 insertions, 3 deletions
| diff --git a/drivers/char/ipmi/ipmi_dmi.c b/drivers/char/ipmi/ipmi_dmi.c index ff0b199be472..f2411468f33f 100644 --- a/drivers/char/ipmi/ipmi_dmi.c +++ b/drivers/char/ipmi/ipmi_dmi.c @@ -66,7 +66,6 @@ static void __init dmi_add_platform_ipmi(unsigned long base_addr,  		return;  	} -	memset(&p, 0, sizeof(p));  	p.addr = base_addr;  	p.space = space;  	p.regspacing = offset; diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index e8ba67834746..00bf4b17edbf 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -214,6 +214,9 @@ struct ipmi_user {  	/* Does this interface receive IPMI events? */  	bool gets_events; + +	/* Free must run in process context for RCU cleanup. */ +	struct work_struct remove_work;  };  static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index) @@ -1157,6 +1160,15 @@ static int intf_err_seq(struct ipmi_smi *intf,  	return rv;  } +static void free_user_work(struct work_struct *work) +{ +	struct ipmi_user *user = container_of(work, struct ipmi_user, +					      remove_work); + +	cleanup_srcu_struct(&user->release_barrier); +	kfree(user); +} +  int ipmi_create_user(unsigned int          if_num,  		     const struct ipmi_user_hndl *handler,  		     void                  *handler_data, @@ -1200,6 +1212,8 @@ int ipmi_create_user(unsigned int          if_num,  	goto out_kfree;   found: +	INIT_WORK(&new_user->remove_work, free_user_work); +  	rv = init_srcu_struct(&new_user->release_barrier);  	if (rv)  		goto out_kfree; @@ -1260,8 +1274,9 @@ EXPORT_SYMBOL(ipmi_get_smi_info);  static void free_user(struct kref *ref)  {  	struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount); -	cleanup_srcu_struct(&user->release_barrier); -	kfree(user); + +	/* SRCU cleanup must happen in task context. */ +	schedule_work(&user->remove_work);  }  static void _ipmi_destroy_user(struct ipmi_user *user) diff --git a/drivers/char/ipmi/ipmi_si_hardcode.c b/drivers/char/ipmi/ipmi_si_hardcode.c index 01946cad3d13..682221eebd66 100644 --- a/drivers/char/ipmi/ipmi_si_hardcode.c +++ b/drivers/char/ipmi/ipmi_si_hardcode.c @@ -118,6 +118,8 @@ void __init ipmi_hardcode_init(void)  	char *str;  	char *si_type[SI_MAX_PARMS]; +	memset(si_type, 0, sizeof(si_type)); +  	/* Parse out the si_type string into its components. */  	str = si_type_str;  	if (*str != '\0') { | 
