@@ -2284,6 +2284,7 @@ static int i_ipmi_request(struct ipmi_user *user,
22842284{
22852285 struct ipmi_smi_msg * smi_msg ;
22862286 struct ipmi_recv_msg * recv_msg ;
2287+ int run_to_completion = READ_ONCE (intf -> run_to_completion );
22872288 int rv = 0 ;
22882289
22892290 if (user ) {
@@ -2317,7 +2318,8 @@ static int i_ipmi_request(struct ipmi_user *user,
23172318 }
23182319 }
23192320
2320- mutex_lock (& intf -> users_mutex );
2321+ if (!run_to_completion )
2322+ mutex_lock (& intf -> users_mutex );
23212323 if (intf -> in_shutdown ) {
23222324 rv = - ENODEV ;
23232325 goto out_err ;
@@ -2363,7 +2365,8 @@ static int i_ipmi_request(struct ipmi_user *user,
23632365
23642366 smi_send (intf , intf -> handlers , smi_msg , priority );
23652367 }
2366- mutex_unlock (& intf -> users_mutex );
2368+ if (!run_to_completion )
2369+ mutex_unlock (& intf -> users_mutex );
23672370
23682371out :
23692372 if (rv && user )
@@ -4559,7 +4562,7 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
45594562 && (msg -> data [1 ] == IPMI_SEND_MSG_CMD )
45604563 && (msg -> user_data == NULL )) {
45614564
4562- if (intf -> in_shutdown )
4565+ if (intf -> in_shutdown || intf -> run_to_completion )
45634566 goto out ;
45644567
45654568 /*
@@ -4631,6 +4634,9 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
46314634 */
46324635 struct ipmi_recv_msg * recv_msg ;
46334636
4637+ if (intf -> run_to_completion )
4638+ goto out ;
4639+
46344640 chan = msg -> data [2 ] & 0x0f ;
46354641 if (chan >= IPMI_MAX_CHANNELS )
46364642 /* Invalid channel number */
@@ -4653,6 +4659,9 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
46534659 && (msg -> rsp [1 ] == IPMI_GET_MSG_CMD )) {
46544660 struct ipmi_channel * chans ;
46554661
4662+ if (intf -> run_to_completion )
4663+ goto out ;
4664+
46564665 /* It's from the receive queue. */
46574666 chan = msg -> rsp [3 ] & 0xf ;
46584667 if (chan >= IPMI_MAX_CHANNELS ) {
@@ -4727,6 +4736,9 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
47274736 } else if ((msg -> rsp [0 ] == ((IPMI_NETFN_APP_REQUEST |1 ) << 2 ))
47284737 && (msg -> rsp [1 ] == IPMI_READ_EVENT_MSG_BUFFER_CMD )) {
47294738 /* It's an asynchronous event. */
4739+ if (intf -> run_to_completion )
4740+ goto out ;
4741+
47304742 requeue = handle_read_event_rsp (intf , msg );
47314743 } else {
47324744 /* It's a response from the local BMC. */
@@ -4855,15 +4867,6 @@ static void smi_work(struct work_struct *t)
48554867
48564868 list_del (& msg -> link );
48574869
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- */
48674870 if (refcount_read (& user -> destroyed ) == 0 ) {
48684871 ipmi_free_recv_msg (msg );
48694872 } else {
@@ -5222,9 +5225,9 @@ static void dummy_recv_done_handler(struct ipmi_recv_msg *msg)
52225225/*
52235226 * Inside a panic, send a message and wait for a response.
52245227 */
5225- static void ipmi_panic_request_and_wait (struct ipmi_smi * intf ,
5226- struct ipmi_addr * addr ,
5227- struct kernel_ipmi_msg * msg )
5228+ static void _ipmi_panic_request_and_wait (struct ipmi_smi * intf ,
5229+ struct ipmi_addr * addr ,
5230+ struct kernel_ipmi_msg * msg )
52285231{
52295232 struct ipmi_smi_msg smi_msg ;
52305233 struct ipmi_recv_msg recv_msg ;
@@ -5254,6 +5257,15 @@ static void ipmi_panic_request_and_wait(struct ipmi_smi *intf,
52545257 ipmi_poll (intf );
52555258}
52565259
5260+ void ipmi_panic_request_and_wait (struct ipmi_user * user ,
5261+ struct ipmi_addr * addr ,
5262+ struct kernel_ipmi_msg * msg )
5263+ {
5264+ user -> intf -> run_to_completion = 1 ;
5265+ _ipmi_panic_request_and_wait (user -> intf , addr , msg );
5266+ }
5267+ EXPORT_SYMBOL (ipmi_panic_request_and_wait );
5268+
52575269static void event_receiver_fetcher (struct ipmi_smi * intf ,
52585270 struct ipmi_recv_msg * msg )
52595271{
@@ -5322,7 +5334,7 @@ static void send_panic_events(struct ipmi_smi *intf, char *str)
53225334 }
53235335
53245336 /* Send the event announcing the panic. */
5325- ipmi_panic_request_and_wait (intf , & addr , & msg );
5337+ _ipmi_panic_request_and_wait (intf , & addr , & msg );
53265338
53275339 /*
53285340 * On every interface, dump a bunch of OEM event holding the
@@ -5358,7 +5370,7 @@ static void send_panic_events(struct ipmi_smi *intf, char *str)
53585370 msg .data = NULL ;
53595371 msg .data_len = 0 ;
53605372 intf -> null_user_handler = device_id_fetcher ;
5361- ipmi_panic_request_and_wait (intf , & addr , & msg );
5373+ _ipmi_panic_request_and_wait (intf , & addr , & msg );
53625374
53635375 if (intf -> local_event_generator ) {
53645376 /* Request the event receiver from the local MC. */
@@ -5367,7 +5379,7 @@ static void send_panic_events(struct ipmi_smi *intf, char *str)
53675379 msg .data = NULL ;
53685380 msg .data_len = 0 ;
53695381 intf -> null_user_handler = event_receiver_fetcher ;
5370- ipmi_panic_request_and_wait (intf , & addr , & msg );
5382+ _ipmi_panic_request_and_wait (intf , & addr , & msg );
53715383 }
53725384 intf -> null_user_handler = NULL ;
53735385
@@ -5419,7 +5431,7 @@ static void send_panic_events(struct ipmi_smi *intf, char *str)
54195431 memcpy_and_pad (data + 5 , 11 , p , size , '\0' );
54205432 p += size ;
54215433
5422- ipmi_panic_request_and_wait (intf , & addr , & msg );
5434+ _ipmi_panic_request_and_wait (intf , & addr , & msg );
54235435 }
54245436}
54255437
0 commit comments