@@ -1327,6 +1327,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
1327
1327
unsigned long flags ;
1328
1328
struct cmd_rcvr * rcvr ;
1329
1329
struct cmd_rcvr * rcvrs = NULL ;
1330
+ struct ipmi_recv_msg * msg , * msg2 ;
1330
1331
1331
1332
if (!refcount_dec_if_one (& user -> destroyed ))
1332
1333
return ;
@@ -1377,6 +1378,15 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
1377
1378
kfree (rcvr );
1378
1379
}
1379
1380
1381
+ mutex_lock (& intf -> user_msgs_mutex );
1382
+ list_for_each_entry_safe (msg , msg2 , & intf -> user_msgs , link ) {
1383
+ if (msg -> user != user )
1384
+ continue ;
1385
+ list_del (& msg -> link );
1386
+ ipmi_free_recv_msg (msg );
1387
+ }
1388
+ mutex_unlock (& intf -> user_msgs_mutex );
1389
+
1380
1390
release_ipmi_user (user );
1381
1391
}
1382
1392
@@ -4844,8 +4854,22 @@ static void smi_work(struct work_struct *t)
4844
4854
struct ipmi_user * user = msg -> user ;
4845
4855
4846
4856
list_del (& msg -> link );
4847
- atomic_dec (& user -> nr_msgs );
4848
- user -> handler -> ipmi_recv_hndl (msg , user -> handler_data );
4857
+
4858
+ /*
4859
+ * I would like for this check (and user->destroyed)
4860
+ * to go away, but it's possible that an interface is
4861
+ * processing a message that belongs to the user while
4862
+ * the user is being deleted. When that response
4863
+ * comes back, it could be queued after the user is
4864
+ * destroyed. This is simpler than handling it in the
4865
+ * interface.
4866
+ */
4867
+ if (refcount_read (& user -> destroyed ) == 0 ) {
4868
+ ipmi_free_recv_msg (msg );
4869
+ } else {
4870
+ atomic_dec (& user -> nr_msgs );
4871
+ user -> handler -> ipmi_recv_hndl (msg , user -> handler_data );
4872
+ }
4849
4873
}
4850
4874
mutex_unlock (& intf -> user_msgs_mutex );
4851
4875
0 commit comments