소스 검색

[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 9 년 전
부모
커밋
cd68d93b6e
1개의 변경된 파일20개의 추가작업 그리고 24개의 파일을 삭제
  1. 20
    24
      src/drivers/net/netvsc.c

+ 20
- 24
src/drivers/net/netvsc.c 파일 보기

@@ -262,8 +262,11 @@ static int netvsc_revoke_buffer ( struct netvsc_device *netvsc,
262 262
 
263 263
 	/* Send message and wait for completion */
264 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 268
 		return rc;
269
+	}
267 270
 
268 271
 	return 0;
269 272
 }
@@ -637,14 +640,8 @@ static int netvsc_create_buffer ( struct netvsc_device *netvsc,
637 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 643
 	return 0;
645 644
 
646
-	netvsc_revoke_buffer ( netvsc, buffer );
647
- err_establish_buffer:
648 645
 	vmbus_unregister_pages ( vmdev, &buffer->pages );
649 646
  err_register_pages:
650 647
 	vmbus_gpadl_teardown ( vmdev, gpadl );
@@ -665,16 +662,6 @@ static void netvsc_destroy_buffer ( struct netvsc_device *netvsc,
665 662
 	struct vmbus_device *vmdev = netvsc->vmdev;
666 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 665
 	/* Unregister transfer pages */
679 666
 	vmbus_unregister_pages ( vmdev, &buffer->pages );
680 667
 
@@ -704,6 +691,10 @@ static int netvsc_open ( struct rndis_device *rndis ) {
704 691
 	struct netvsc_device *netvsc = rndis->priv;
705 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 698
 	/* Open channel */
708 699
 	if ( ( rc = vmbus_open ( netvsc->vmdev, &netvsc_channel_operations,
709 700
 				 PAGE_SIZE, PAGE_SIZE, NETVSC_MTU ) ) != 0 ) {
@@ -722,20 +713,22 @@ static int netvsc_open ( struct rndis_device *rndis ) {
722 713
 	if ( ( rc = netvsc_create_ring ( netvsc, &netvsc->tx ) ) != 0 )
723 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 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 724
 	netvsc_destroy_ring ( netvsc, &netvsc->tx, NULL );
734 725
  err_create_tx:
735 726
  err_ndis_version:
736 727
  err_initialise:
737 728
 	vmbus_close ( netvsc->vmdev );
738 729
  err_vmbus_open:
730
+	netvsc_destroy_buffer ( netvsc, &netvsc->rx );
731
+ err_create_rx:
739 732
 	return rc;
740 733
 }
741 734
 
@@ -747,14 +740,17 @@ static int netvsc_open ( struct rndis_device *rndis ) {
747 740
 static void netvsc_close ( struct rndis_device *rndis ) {
748 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 746
 	/* Destroy transmit ring */
754 747
 	netvsc_destroy_ring ( netvsc, &netvsc->tx, netvsc_cancel_transmit );
755 748
 
756 749
 	/* Close channel */
757 750
 	vmbus_close ( netvsc->vmdev );
751
+
752
+	/* Destroy receive buffer */
753
+	netvsc_destroy_buffer ( netvsc, &netvsc->rx );
758 754
 }
759 755
 
760 756
 /** RNDIS operations */

Loading…
취소
저장