@@ -2284,6 +2284,7 @@ static int i_ipmi_request(struct ipmi_user *user,
2284
2284
{
2285
2285
struct ipmi_smi_msg * smi_msg ;
2286
2286
struct ipmi_recv_msg * recv_msg ;
2287
+ int run_to_completion = READ_ONCE (intf -> run_to_completion );
2287
2288
int rv = 0 ;
2288
2289
2289
2290
if (user ) {
@@ -2317,7 +2318,8 @@ static int i_ipmi_request(struct ipmi_user *user,
2317
2318
}
2318
2319
}
2319
2320
2320
- mutex_lock (& intf -> users_mutex );
2321
+ if (!run_to_completion )
2322
+ mutex_lock (& intf -> users_mutex );
2321
2323
if (intf -> in_shutdown ) {
2322
2324
rv = - ENODEV ;
2323
2325
goto out_err ;
@@ -2363,7 +2365,8 @@ static int i_ipmi_request(struct ipmi_user *user,
2363
2365
2364
2366
smi_send (intf , intf -> handlers , smi_msg , priority );
2365
2367
}
2366
- mutex_unlock (& intf -> users_mutex );
2368
+ if (!run_to_completion )
2369
+ mutex_unlock (& intf -> users_mutex );
2367
2370
2368
2371
out :
2369
2372
if (rv && user )
@@ -4559,7 +4562,7 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
4559
4562
&& (msg -> data [1 ] == IPMI_SEND_MSG_CMD )
4560
4563
&& (msg -> user_data == NULL )) {
4561
4564
4562
- if (intf -> in_shutdown )
4565
+ if (intf -> in_shutdown || intf -> run_to_completion )
4563
4566
goto out ;
4564
4567
4565
4568
/*
@@ -4631,6 +4634,9 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
4631
4634
*/
4632
4635
struct ipmi_recv_msg * recv_msg ;
4633
4636
4637
+ if (intf -> run_to_completion )
4638
+ goto out ;
4639
+
4634
4640
chan = msg -> data [2 ] & 0x0f ;
4635
4641
if (chan >= IPMI_MAX_CHANNELS )
4636
4642
/* Invalid channel number */
@@ -4653,6 +4659,9 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
4653
4659
&& (msg -> rsp [1 ] == IPMI_GET_MSG_CMD )) {
4654
4660
struct ipmi_channel * chans ;
4655
4661
4662
+ if (intf -> run_to_completion )
4663
+ goto out ;
4664
+
4656
4665
/* It's from the receive queue. */
4657
4666
chan = msg -> rsp [3 ] & 0xf ;
4658
4667
if (chan >= IPMI_MAX_CHANNELS ) {
@@ -4727,6 +4736,9 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
4727
4736
} else if ((msg -> rsp [0 ] == ((IPMI_NETFN_APP_REQUEST |1 ) << 2 ))
4728
4737
&& (msg -> rsp [1 ] == IPMI_READ_EVENT_MSG_BUFFER_CMD )) {
4729
4738
/* It's an asynchronous event. */
4739
+ if (intf -> run_to_completion )
4740
+ goto out ;
4741
+
4730
4742
requeue = handle_read_event_rsp (intf , msg );
4731
4743
} else {
4732
4744
/* It's a response from the local BMC. */
@@ -4855,15 +4867,6 @@ static void smi_work(struct work_struct *t)
4855
4867
4856
4868
list_del (& msg -> link );
4857
4869
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
4870
if (refcount_read (& user -> destroyed ) == 0 ) {
4868
4871
ipmi_free_recv_msg (msg );
4869
4872
} else {
@@ -5222,9 +5225,9 @@ static void dummy_recv_done_handler(struct ipmi_recv_msg *msg)
5222
5225
/*
5223
5226
* Inside a panic, send a message and wait for a response.
5224
5227
*/
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 )
5228
5231
{
5229
5232
struct ipmi_smi_msg smi_msg ;
5230
5233
struct ipmi_recv_msg recv_msg ;
@@ -5254,6 +5257,15 @@ static void ipmi_panic_request_and_wait(struct ipmi_smi *intf,
5254
5257
ipmi_poll (intf );
5255
5258
}
5256
5259
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
+
5257
5269
static void event_receiver_fetcher (struct ipmi_smi * intf ,
5258
5270
struct ipmi_recv_msg * msg )
5259
5271
{
@@ -5322,7 +5334,7 @@ static void send_panic_events(struct ipmi_smi *intf, char *str)
5322
5334
}
5323
5335
5324
5336
/* Send the event announcing the panic. */
5325
- ipmi_panic_request_and_wait (intf , & addr , & msg );
5337
+ _ipmi_panic_request_and_wait (intf , & addr , & msg );
5326
5338
5327
5339
/*
5328
5340
* 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)
5358
5370
msg .data = NULL ;
5359
5371
msg .data_len = 0 ;
5360
5372
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 );
5362
5374
5363
5375
if (intf -> local_event_generator ) {
5364
5376
/* Request the event receiver from the local MC. */
@@ -5367,7 +5379,7 @@ static void send_panic_events(struct ipmi_smi *intf, char *str)
5367
5379
msg .data = NULL ;
5368
5380
msg .data_len = 0 ;
5369
5381
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 );
5371
5383
}
5372
5384
intf -> null_user_handler = NULL ;
5373
5385
@@ -5419,7 +5431,7 @@ static void send_panic_events(struct ipmi_smi *intf, char *str)
5419
5431
memcpy_and_pad (data + 5 , 11 , p , size , '\0' );
5420
5432
p += size ;
5421
5433
5422
- ipmi_panic_request_and_wait (intf , & addr , & msg );
5434
+ _ipmi_panic_request_and_wait (intf , & addr , & msg );
5423
5435
}
5424
5436
}
5425
5437
0 commit comments