@@ -214,6 +214,9 @@ struct ipmi_user {
214
214
215
215
/* Does this interface receive IPMI events? */
216
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
219
222
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,
1157
1160
return rv ;
1158
1161
}
1159
1162
1163
+ static 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
+
1160
1172
int ipmi_create_user (unsigned int if_num ,
1161
1173
const struct ipmi_user_hndl * handler ,
1162
1174
void * handler_data ,
@@ -1200,6 +1212,8 @@ int ipmi_create_user(unsigned int if_num,
1200
1212
goto out_kfree ;
1201
1213
1202
1214
found :
1215
+ INIT_WORK (& new_user -> remove_work , free_user_work );
1216
+
1203
1217
rv = init_srcu_struct (& new_user -> release_barrier );
1204
1218
if (rv )
1205
1219
goto out_kfree ;
@@ -1260,8 +1274,9 @@ EXPORT_SYMBOL(ipmi_get_smi_info);
1260
1274
static void free_user (struct kref * ref )
1261
1275
{
1262
1276
struct ipmi_user * user = container_of (ref , struct ipmi_user , refcount );
1263
- cleanup_srcu_struct (& user -> release_barrier );
1264
- kfree (user );
1277
+
1278
+ /* SRCU cleanup must happen in task context. */
1279
+ schedule_work (& user -> remove_work );
1265
1280
}
1266
1281
1267
1282
static void _ipmi_destroy_user (struct ipmi_user * user )
0 commit comments