[ipxe-devel] [RFC PATCH 2/8] vmbus: encapsulate obsolete gpadl handling

Roman Kagan rkagan at virtuozzo.com
Mon Jun 11 17:28:17 UTC 2018


The handling of obsolete GPADLs, which is basically a hack for
reasonably graceful handover of VMBus ownership between the BIOS and
iPXE, is an implementation detail and can be made private to vmbus.c.

The callers (netvsc.c) can get by receiving -EPIPE from vmbus_send_* or
vmbus_poll.

Signed-off-by: Roman Kagan <rkagan at virtuozzo.com>
---
 src/drivers/net/netvsc.h     | 15 ---------------
 src/include/ipxe/vmbus.h     | 17 -----------------
 src/drivers/net/netvsc.c     | 17 -----------------
 src/interface/hyperv/vmbus.c | 25 ++++++++++++++++++++++++-
 4 files changed, 24 insertions(+), 50 deletions(-)

diff --git a/src/drivers/net/netvsc.h b/src/drivers/net/netvsc.h
index 93192357..39eeb891 100644
--- a/src/drivers/net/netvsc.h
+++ b/src/drivers/net/netvsc.h
@@ -362,19 +362,4 @@ struct netvsc_device {
 	int wait_rc;
 };
 
-/**
- * Check if NetVSC device is obsolete
- *
- * @v netvsc		NetVSC device
- * @v is_obsolete	NetVSC device is obsolete
- *
- * Check if NetVSC device is obsolete (i.e. was opened before the most
- * recent Hyper-V reset).
- */
-static inline __attribute__ (( always_inline )) int
-netvsc_is_obsolete ( struct netvsc_device *netvsc ) {
-
-	return vmbus_gpadl_is_obsolete ( netvsc->rx.gpadl );
-}
-
 #endif /* _NETVSC_H */
diff --git a/src/include/ipxe/vmbus.h b/src/include/ipxe/vmbus.h
index 68244185..dd8f35e7 100644
--- a/src/include/ipxe/vmbus.h
+++ b/src/include/ipxe/vmbus.h
@@ -617,23 +617,6 @@ vmbus_unregister_pages ( struct vmbus_device *vmdev,
 	list_del ( &pages->list );
 }
 
-extern unsigned int vmbus_obsolete_gpadl;
-
-/**
- * Check if GPADL is obsolete
- *
- * @v gpadl		GPADL ID
- * @v is_obsolete	GPADL ID is obsolete
- *
- * Check if GPADL is obsolete (i.e. was created before the most recent
- * Hyper-V reset).
- */
-static inline __attribute__ (( always_inline )) int
-vmbus_gpadl_is_obsolete ( unsigned int gpadl ) {
-
-	return ( gpadl <= vmbus_obsolete_gpadl );
-}
-
 extern int vmbus_establish_gpadl ( struct vmbus_device *vmdev, userptr_t data,
 				   size_t len );
 extern int vmbus_gpadl_teardown ( struct vmbus_device *vmdev,
diff --git a/src/drivers/net/netvsc.c b/src/drivers/net/netvsc.c
index 5be52fb8..eb880180 100644
--- a/src/drivers/net/netvsc.c
+++ b/src/drivers/net/netvsc.c
@@ -259,15 +259,6 @@ static int netvsc_revoke_buffer ( struct netvsc_device *netvsc,
 	struct netvsc_revoke_buffer_message msg;
 	int rc;
 
-	/* If the buffer's GPADL is obsolete (i.e. was created before
-	 * the most recent Hyper-V reset), then we will never receive
-	 * a response to the revoke message.  Since the GPADL is
-	 * already destroyed as far as the hypervisor is concerned, no
-	 * further action is required.
-	 */
-	if ( netvsc_is_obsolete ( netvsc ) )
-		return 0;
-
 	/* Construct message */
 	memset ( &msg, 0, sizeof ( msg ) );
 	msg.header.type = cpu_to_le32 ( buffer->revoke_type );
@@ -483,14 +474,6 @@ static int netvsc_transmit ( struct rndis_device *rndis,
 	uint64_t xid;
 	int rc;
 
-	/* If the device is obsolete (i.e. was opened before the most
-	 * recent Hyper-V reset), then we will never receive transmit
-	 * completions.  Fail transmissions immediately to minimise
-	 * the delay in closing and reopening the device.
-	 */
-	if ( netvsc_is_obsolete ( netvsc ) )
-		return -EPIPE;
-
 	/* Sanity check */
 	assert ( iob_len ( iobuf ) >= sizeof ( *header ) );
 	assert ( iob_len ( iobuf ) == le32_to_cpu ( header->len ) );
diff --git a/src/interface/hyperv/vmbus.c b/src/interface/hyperv/vmbus.c
index 529b2bf8..8a340959 100644
--- a/src/interface/hyperv/vmbus.c
+++ b/src/interface/hyperv/vmbus.c
@@ -58,7 +58,22 @@ static unsigned int vmbus_gpadl = VMBUS_GPADL_MAGIC;
  * When the Hyper-V connection is reset, any previous GPADLs are
  * automatically rendered obsolete.
  */
-unsigned int vmbus_obsolete_gpadl;
+static unsigned int vmbus_obsolete_gpadl;
+
+/**
+ * Check if GPADL is obsolete
+ *
+ * @v gpadl		GPADL ID
+ * @v is_obsolete	GPADL ID is obsolete
+ *
+ * Check if GPADL is obsolete (i.e. was created before the most recent
+ * Hyper-V reset).
+ */
+static inline __attribute__ (( always_inline )) int
+vmbus_gpadl_is_obsolete ( unsigned int gpadl ) {
+
+	return ( gpadl <= vmbus_obsolete_gpadl );
+}
 
 /**
  * Post message
@@ -693,6 +708,10 @@ static int vmbus_send ( struct vmbus_device *vmdev,
 	/* Sanity check */
 	assert ( vmdev->out != NULL );
 
+	/* We're in process of being reset */
+	if ( vmbus_gpadl_is_obsolete ( vmdev->gpadl ) )
+		return -EPIPE;
+
 	/* Calculate lengths */
 	header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
 	pad_len = ( ( -len ) & ( 8 - 1 ) );
@@ -986,6 +1005,10 @@ int vmbus_poll ( struct vmbus_device *vmdev ) {
 	assert ( vmdev->packet != NULL );
 	assert ( vmdev->in != NULL );
 
+	/* We're in process of being reset */
+	if ( vmbus_gpadl_is_obsolete ( vmdev->gpadl ) )
+		return -EPIPE;
+
 	/* Return immediately if buffer is empty */
 	if ( ! vmbus_has_data ( vmdev ) )
 		return 0;
-- 
2.17.1




More information about the ipxe-devel mailing list