aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/ipmi/ipmi_dmi.c1
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c19
-rw-r--r--drivers/char/ipmi/ipmi_si_hardcode.c2
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,
66 return; 66 return;
67 } 67 }
68 68
69 memset(&p, 0, sizeof(p));
70 p.addr = base_addr; 69 p.addr = base_addr;
71 p.space = space; 70 p.space = space;
72 p.regspacing = offset; 71 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 {
214 214
215 /* Does this interface receive IPMI events? */ 215 /* Does this interface receive IPMI events? */
216 bool gets_events; 216 bool gets_events;
217
218 /* Free must run in process context for RCU cleanup. */
219 struct work_struct remove_work;
217}; 220};
218 221
219static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index) 222static 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,
1157 return rv; 1160 return rv;
1158} 1161}
1159 1162
1163static void free_user_work(struct work_struct *work)
1164{
1165 struct ipmi_user *user = container_of(work, struct ipmi_user,
1166 remove_work);
1167
1168 cleanup_srcu_struct(&user->release_barrier);
1169 kfree(user);
1170}
1171
1160int ipmi_create_user(unsigned int if_num, 1172int ipmi_create_user(unsigned int if_num,
1161 const struct ipmi_user_hndl *handler, 1173 const struct ipmi_user_hndl *handler,
1162 void *handler_data, 1174 void *handler_data,
@@ -1200,6 +1212,8 @@ int ipmi_create_user(unsigned int if_num,
1200 goto out_kfree; 1212 goto out_kfree;
1201 1213
1202 found: 1214 found:
1215 INIT_WORK(&new_user->remove_work, free_user_work);
1216
1203 rv = init_srcu_struct(&new_user->release_barrier); 1217 rv = init_srcu_struct(&new_user->release_barrier);
1204 if (rv) 1218 if (rv)
1205 goto out_kfree; 1219 goto out_kfree;
@@ -1260,8 +1274,9 @@ EXPORT_SYMBOL(ipmi_get_smi_info);
1260static void free_user(struct kref *ref) 1274static void free_user(struct kref *ref)
1261{ 1275{
1262 struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount); 1276 struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount);
1263 cleanup_srcu_struct(&user->release_barrier); 1277
1264 kfree(user); 1278 /* SRCU cleanup must happen in task context. */
1279 schedule_work(&user->remove_work);
1265} 1280}
1266 1281
1267static void _ipmi_destroy_user(struct ipmi_user *user) 1282static 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)
118 char *str; 118 char *str;
119 char *si_type[SI_MAX_PARMS]; 119 char *si_type[SI_MAX_PARMS];
120 120
121 memset(si_type, 0, sizeof(si_type));
122
121 /* Parse out the si_type string into its components. */ 123 /* Parse out the si_type string into its components. */
122 str = si_type_str; 124 str = si_type_str;
123 if (*str != '\0') { 125 if (*str != '\0') {