@@ -428,15 +428,13 @@ void vmbus_free_channels(void)
428
428
{
429
429
struct vmbus_channel * channel , * tmp ;
430
430
431
- mutex_lock (& vmbus_connection .channel_mutex );
432
431
list_for_each_entry_safe (channel , tmp , & vmbus_connection .chn_list ,
433
432
listentry ) {
434
433
/* hv_process_channel_removal() needs this */
435
434
channel -> rescind = true;
436
435
437
436
vmbus_device_unregister (channel -> device_obj );
438
437
}
439
- mutex_unlock (& vmbus_connection .channel_mutex );
440
438
}
441
439
442
440
/*
@@ -483,8 +481,10 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
483
481
list_add_tail (& newchannel -> sc_list , & channel -> sc_list );
484
482
channel -> num_sc ++ ;
485
483
spin_unlock_irqrestore (& channel -> lock , flags );
486
- } else
484
+ } else {
485
+ atomic_dec (& vmbus_connection .offer_in_progress );
487
486
goto err_free_chan ;
487
+ }
488
488
}
489
489
490
490
dev_type = hv_get_dev_type (newchannel );
@@ -511,6 +511,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
511
511
if (!fnew ) {
512
512
if (channel -> sc_creation_callback != NULL )
513
513
channel -> sc_creation_callback (newchannel );
514
+ atomic_dec (& vmbus_connection .offer_in_progress );
514
515
return ;
515
516
}
516
517
@@ -532,16 +533,16 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
532
533
* binding which eventually invokes the device driver's AddDevice()
533
534
* method.
534
535
*/
535
- mutex_lock (& vmbus_connection .channel_mutex );
536
536
ret = vmbus_device_register (newchannel -> device_obj );
537
- mutex_unlock (& vmbus_connection .channel_mutex );
538
537
539
538
if (ret != 0 ) {
540
539
pr_err ("unable to add child device object (relid %d)\n" ,
541
540
newchannel -> offermsg .child_relid );
542
541
kfree (newchannel -> device_obj );
543
542
goto err_deq_chan ;
544
543
}
544
+
545
+ atomic_dec (& vmbus_connection .offer_in_progress );
545
546
return ;
546
547
547
548
err_deq_chan :
@@ -797,6 +798,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
797
798
newchannel = alloc_channel ();
798
799
if (!newchannel ) {
799
800
vmbus_release_relid (offer -> child_relid );
801
+ atomic_dec (& vmbus_connection .offer_in_progress );
800
802
pr_err ("Unable to allocate channel object\n" );
801
803
return ;
802
804
}
@@ -843,16 +845,38 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
843
845
844
846
rescind = (struct vmbus_channel_rescind_offer * )hdr ;
845
847
848
+ /*
849
+ * The offer msg and the corresponding rescind msg
850
+ * from the host are guranteed to be ordered -
851
+ * offer comes in first and then the rescind.
852
+ * Since we process these events in work elements,
853
+ * and with preemption, we may end up processing
854
+ * the events out of order. Given that we handle these
855
+ * work elements on the same CPU, this is possible only
856
+ * in the case of preemption. In any case wait here
857
+ * until the offer processing has moved beyond the
858
+ * point where the channel is discoverable.
859
+ */
860
+
861
+ while (atomic_read (& vmbus_connection .offer_in_progress ) != 0 ) {
862
+ /*
863
+ * We wait here until any channel offer is currently
864
+ * being processed.
865
+ */
866
+ msleep (1 );
867
+ }
868
+
846
869
mutex_lock (& vmbus_connection .channel_mutex );
847
870
channel = relid2channel (rescind -> child_relid );
871
+ mutex_unlock (& vmbus_connection .channel_mutex );
848
872
849
873
if (channel == NULL ) {
850
874
/*
851
- * This is very impossible, because in
852
- * vmbus_process_offer(), we have already invoked
853
- * vmbus_release_relid() on error .
875
+ * We failed in processing the offer message;
876
+ * we would have cleaned up the relid in that
877
+ * failure path .
854
878
*/
855
- goto out ;
879
+ return ;
856
880
}
857
881
858
882
spin_lock_irqsave (& channel -> lock , flags );
@@ -864,7 +888,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
864
888
if (channel -> device_obj ) {
865
889
if (channel -> chn_rescind_callback ) {
866
890
channel -> chn_rescind_callback (channel );
867
- goto out ;
891
+ return ;
868
892
}
869
893
/*
870
894
* We will have to unregister this device from the
@@ -875,13 +899,26 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
875
899
vmbus_device_unregister (channel -> device_obj );
876
900
put_device (dev );
877
901
}
878
- } else {
879
- hv_process_channel_removal (channel ,
880
- channel -> offermsg .child_relid );
881
902
}
882
-
883
- out :
884
- mutex_unlock (& vmbus_connection .channel_mutex );
903
+ if (channel -> primary_channel != NULL ) {
904
+ /*
905
+ * Sub-channel is being rescinded. Following is the channel
906
+ * close sequence when initiated from the driveri (refer to
907
+ * vmbus_close() for details):
908
+ * 1. Close all sub-channels first
909
+ * 2. Then close the primary channel.
910
+ */
911
+ if (channel -> state == CHANNEL_OPEN_STATE ) {
912
+ /*
913
+ * The channel is currently not open;
914
+ * it is safe for us to cleanup the channel.
915
+ */
916
+ mutex_lock (& vmbus_connection .channel_mutex );
917
+ hv_process_channel_removal (channel ,
918
+ channel -> offermsg .child_relid );
919
+ mutex_unlock (& vmbus_connection .channel_mutex );
920
+ }
921
+ }
885
922
}
886
923
887
924
void vmbus_hvsock_device_unregister (struct vmbus_channel * channel )
0 commit comments