Procházet zdrojové kódy

[hyperv] Tear down NetVSC RX buffer GPADL after closing VMBus device

On Windows Server 2012 R2, the receive buffer teardown completion
message seems to occasionally be deferred until after the VMBus
channel has been closed.  This happens even if there are no packets
currently in the receive buffer.

Work around this problem by separating the revocation and teardown of
the receive buffer, and deferring the teardown until after the VMBus
channel has been closed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown před 9 roky
rodič
revize
cd68d93b6e
1 změnil soubory, kde provedl 20 přidání a 24 odebrání
  1. 20
    24
      src/drivers/net/netvsc.c

+ 20
- 24
src/drivers/net/netvsc.c Zobrazit soubor

262
 
262
 
263
 	/* Send message and wait for completion */
263
 	/* Send message and wait for completion */
264
 	if ( ( rc = netvsc_control ( netvsc, buffer->revoke_xrid,
264
 	if ( ( rc = netvsc_control ( netvsc, buffer->revoke_xrid,
265
-				     &msg, sizeof ( msg ) ) ) != 0 )
265
+				     &msg, sizeof ( msg ) ) ) != 0 ) {
266
+		DBGC ( netvsc, "NETVSC %s could not revoke buffer: %s\n",
267
+		       netvsc->name, strerror ( rc ) );
266
 		return rc;
268
 		return rc;
269
+	}
267
 
270
 
268
 	return 0;
271
 	return 0;
269
 }
272
 }
637
 		goto err_register_pages;
640
 		goto err_register_pages;
638
 	}
641
 	}
639
 
642
 
640
-	/* Establish data buffer */
641
-	if ( ( rc = netvsc_establish_buffer ( netvsc, buffer ) ) != 0 )
642
-		goto err_establish_buffer;
643
-
644
 	return 0;
643
 	return 0;
645
 
644
 
646
-	netvsc_revoke_buffer ( netvsc, buffer );
647
- err_establish_buffer:
648
 	vmbus_unregister_pages ( vmdev, &buffer->pages );
645
 	vmbus_unregister_pages ( vmdev, &buffer->pages );
649
  err_register_pages:
646
  err_register_pages:
650
 	vmbus_gpadl_teardown ( vmdev, gpadl );
647
 	vmbus_gpadl_teardown ( vmdev, gpadl );
665
 	struct vmbus_device *vmdev = netvsc->vmdev;
662
 	struct vmbus_device *vmdev = netvsc->vmdev;
666
 	int rc;
663
 	int rc;
667
 
664
 
668
-	/* Revoke buffer */
669
-	if ( ( rc = netvsc_revoke_buffer ( netvsc, buffer ) ) != 0 ) {
670
-		DBGC ( netvsc, "NETVSC %s could not revoke buffer: %s\n",
671
-		       netvsc->name, strerror ( rc ) );
672
-		/* Continue to attempt to tear down the GPA descriptor
673
-		 * list, which should forcibly prevent the host from
674
-		 * subsequently accessing this memory.
675
-		 */
676
-	}
677
-
678
 	/* Unregister transfer pages */
665
 	/* Unregister transfer pages */
679
 	vmbus_unregister_pages ( vmdev, &buffer->pages );
666
 	vmbus_unregister_pages ( vmdev, &buffer->pages );
680
 
667
 
704
 	struct netvsc_device *netvsc = rndis->priv;
691
 	struct netvsc_device *netvsc = rndis->priv;
705
 	int rc;
692
 	int rc;
706
 
693
 
694
+	/* Initialise receive buffer */
695
+	if ( ( rc = netvsc_create_buffer ( netvsc, &netvsc->rx ) ) != 0 )
696
+		goto err_create_rx;
697
+
707
 	/* Open channel */
698
 	/* Open channel */
708
 	if ( ( rc = vmbus_open ( netvsc->vmdev, &netvsc_channel_operations,
699
 	if ( ( rc = vmbus_open ( netvsc->vmdev, &netvsc_channel_operations,
709
 				 PAGE_SIZE, PAGE_SIZE, NETVSC_MTU ) ) != 0 ) {
700
 				 PAGE_SIZE, PAGE_SIZE, NETVSC_MTU ) ) != 0 ) {
722
 	if ( ( rc = netvsc_create_ring ( netvsc, &netvsc->tx ) ) != 0 )
713
 	if ( ( rc = netvsc_create_ring ( netvsc, &netvsc->tx ) ) != 0 )
723
 		goto err_create_tx;
714
 		goto err_create_tx;
724
 
715
 
725
-	/* Initialise receive buffer */
726
-	if ( ( rc = netvsc_create_buffer ( netvsc, &netvsc->rx ) ) != 0 )
727
-		goto err_create_rx;
716
+	/* Establish receive buffer */
717
+	if ( ( rc = netvsc_establish_buffer ( netvsc, &netvsc->rx ) ) != 0 )
718
+		goto err_establish_rx;
728
 
719
 
729
 	return 0;
720
 	return 0;
730
 
721
 
731
-	netvsc_destroy_buffer ( netvsc, &netvsc->rx );
732
- err_create_rx:
722
+	netvsc_revoke_buffer ( netvsc, &netvsc->rx );
723
+ err_establish_rx:
733
 	netvsc_destroy_ring ( netvsc, &netvsc->tx, NULL );
724
 	netvsc_destroy_ring ( netvsc, &netvsc->tx, NULL );
734
  err_create_tx:
725
  err_create_tx:
735
  err_ndis_version:
726
  err_ndis_version:
736
  err_initialise:
727
  err_initialise:
737
 	vmbus_close ( netvsc->vmdev );
728
 	vmbus_close ( netvsc->vmdev );
738
  err_vmbus_open:
729
  err_vmbus_open:
730
+	netvsc_destroy_buffer ( netvsc, &netvsc->rx );
731
+ err_create_rx:
739
 	return rc;
732
 	return rc;
740
 }
733
 }
741
 
734
 
747
 static void netvsc_close ( struct rndis_device *rndis ) {
740
 static void netvsc_close ( struct rndis_device *rndis ) {
748
 	struct netvsc_device *netvsc = rndis->priv;
741
 	struct netvsc_device *netvsc = rndis->priv;
749
 
742
 
750
-	/* Destroy receive buffer */
751
-	netvsc_destroy_buffer ( netvsc, &netvsc->rx );
743
+	/* Revoke receive buffer */
744
+	netvsc_revoke_buffer ( netvsc, &netvsc->rx );
752
 
745
 
753
 	/* Destroy transmit ring */
746
 	/* Destroy transmit ring */
754
 	netvsc_destroy_ring ( netvsc, &netvsc->tx, netvsc_cancel_transmit );
747
 	netvsc_destroy_ring ( netvsc, &netvsc->tx, netvsc_cancel_transmit );
755
 
748
 
756
 	/* Close channel */
749
 	/* Close channel */
757
 	vmbus_close ( netvsc->vmdev );
750
 	vmbus_close ( netvsc->vmdev );
751
+
752
+	/* Destroy receive buffer */
753
+	netvsc_destroy_buffer ( netvsc, &netvsc->rx );
758
 }
754
 }
759
 
755
 
760
 /** RNDIS operations */
756
 /** RNDIS operations */

Načítá se…
Zrušit
Uložit