@@ -1327,6 +1327,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
13271327 unsigned long flags ;
13281328 struct cmd_rcvr * rcvr ;
13291329 struct cmd_rcvr * rcvrs = NULL ;
1330+ struct ipmi_recv_msg * msg , * msg2 ;
13301331
13311332 if (!refcount_dec_if_one (& user -> destroyed ))
13321333 return ;
@@ -1377,6 +1378,15 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
13771378 kfree (rcvr );
13781379 }
13791380
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+
13801390 release_ipmi_user (user );
13811391}
13821392
@@ -4844,8 +4854,22 @@ static void smi_work(struct work_struct *t)
48444854 struct ipmi_user * user = msg -> user ;
48454855
48464856 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+ }
48494873 }
48504874 mutex_unlock (& intf -> user_msgs_mutex );
48514875
0 commit comments