svn commit: r302812 - in head/sys/dev/hyperv: include netvsc vmbus

Sepherosa Ziehau sephe at FreeBSD.org
Thu Jul 14 06:59:06 UTC 2016


Author: sephe
Date: Thu Jul 14 06:59:04 2016
New Revision: 302812
URL: https://svnweb.freebsd.org/changeset/base/302812

Log:
  hyperv/vmbus: Nuke the channel open state.
  
  Channel is either opened or not-opened.
  
  MFC after:	1 week
  Sponsored by:	Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D7105

Modified:
  head/sys/dev/hyperv/include/hyperv.h
  head/sys/dev/hyperv/netvsc/hv_net_vsc.c
  head/sys/dev/hyperv/vmbus/hv_channel.c
  head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h

Modified: head/sys/dev/hyperv/include/hyperv.h
==============================================================================
--- head/sys/dev/hyperv/include/hyperv.h	Thu Jul 14 06:48:24 2016	(r302811)
+++ head/sys/dev/hyperv/include/hyperv.h	Thu Jul 14 06:59:04 2016	(r302812)
@@ -244,18 +244,9 @@ typedef struct {
 
 typedef void (*hv_vmbus_pfn_channel_callback)(void *context);
 
-typedef enum {
-	HV_CHANNEL_OFFER_STATE,
-	HV_CHANNEL_OPENING_STATE,
-	HV_CHANNEL_OPEN_STATE,
-	HV_CHANNEL_OPENED_STATE,
-	HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE,
-} hv_vmbus_channel_state;
-
 typedef struct hv_vmbus_channel {
 	device_t			ch_dev;
 	struct vmbus_softc		*vmbus_sc;
-	hv_vmbus_channel_state		state;
 	uint32_t			ch_flags;	/* VMBUS_CHAN_FLAG_ */
 	uint32_t			ch_id;		/* channel id */
 
@@ -337,7 +328,8 @@ typedef struct hv_vmbus_channel {
 	struct task			ch_detach_task;
 	TAILQ_ENTRY(hv_vmbus_channel)	ch_link;
 	uint32_t			ch_subidx;	/* subchan index */
-
+	volatile uint32_t		ch_stflags;	/* atomic-op */
+							/* VMBUS_CHAN_ST_ */
 	struct hyperv_guid		ch_guid_type;
 	struct hyperv_guid		ch_guid_inst;
 
@@ -357,6 +349,9 @@ typedef struct hv_vmbus_channel {
  */
 #define VMBUS_CHAN_FLAG_BATCHREAD	0x0002
 
+#define VMBUS_CHAN_ST_OPENED_SHIFT	0
+#define VMBUS_CHAN_ST_OPENED		(1 << VMBUS_CHAN_ST_OPENED_SHIFT)
+
 static inline void
 hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t on)
 {

Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.c	Thu Jul 14 06:48:24 2016	(r302811)
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c	Thu Jul 14 06:59:04 2016	(r302812)
@@ -719,11 +719,6 @@ hv_nv_on_device_remove(struct hn_softc *
 
 	/* Now, we can close the channel safely */
 
-	if (!destroy_channel) {
-		sc->hn_prichan->state =
-		    HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE;
-	}
-
 	free(sc->hn_prichan->hv_chan_rdbuf, M_NETVSC);
 	hv_vmbus_channel_close(sc->hn_prichan);
 

Modified: head/sys/dev/hyperv/vmbus/hv_channel.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel.c	Thu Jul 14 06:48:24 2016	(r302811)
+++ head/sys/dev/hyperv/vmbus/hv_channel.c	Thu Jul 14 06:59:04 2016	(r302812)
@@ -191,17 +191,9 @@ hv_vmbus_channel_open(
 		return EINVAL;
 	}
 
-	mtx_lock(&new_channel->sc_lock);
-	if (new_channel->state == HV_CHANNEL_OPEN_STATE) {
-	    new_channel->state = HV_CHANNEL_OPENING_STATE;
-	} else {
-	    mtx_unlock(&new_channel->sc_lock);
-	    if(bootverbose)
-		printf("VMBUS: Trying to open channel <%p> which in "
-		    "%d state.\n", new_channel, new_channel->state);
-	    return (EINVAL);
-	}
-	mtx_unlock(&new_channel->sc_lock);
+	if (atomic_testandset_int(&new_channel->ch_stflags,
+	    VMBUS_CHAN_ST_OPENED_SHIFT))
+		panic("double-open chan%u", new_channel->ch_id);
 
 	new_channel->on_channel_callback = pfn_on_channel_callback;
 	new_channel->channel_callback_context = context;
@@ -223,8 +215,10 @@ hv_vmbus_channel_open(
 	    M_DEVBUF, M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
 	KASSERT(out != NULL,
 	    ("Error VMBUS: contigmalloc failed to allocate Ring Buffer!"));
-	if (out == NULL)
-		return (ENOMEM);
+	if (out == NULL) {
+		ret = ENOMEM;
+		goto failed;
+	}
 
 	in = ((uint8_t *) out + send_ring_buffer_size);
 
@@ -265,7 +259,8 @@ hv_vmbus_channel_open(
 		device_printf(sc->vmbus_dev,
 		    "can not get msg hypercall for chopen(chan%u)\n",
 		    new_channel->ch_id);
-		return ENXIO;
+		ret = ENXIO;
+		goto failed;
 	}
 
 	req = vmbus_msghc_dataptr(mh);
@@ -284,7 +279,7 @@ hv_vmbus_channel_open(
 		    "chopen(chan%u) msg hypercall exec failed: %d\n",
 		    new_channel->ch_id, ret);
 		vmbus_msghc_put(sc, mh);
-		return ret;
+		goto failed;
 	}
 
 	msg = vmbus_msghc_wait_result(sc, mh);
@@ -294,17 +289,20 @@ hv_vmbus_channel_open(
 	vmbus_msghc_put(sc, mh);
 
 	if (status == 0) {
-		new_channel->state = HV_CHANNEL_OPENED_STATE;
 		if (bootverbose) {
 			device_printf(sc->vmbus_dev, "chan%u opened\n",
 			    new_channel->ch_id);
 		}
-	} else {
-		device_printf(sc->vmbus_dev, "failed to open chan%u\n",
-		    new_channel->ch_id);
-		ret = ENXIO;
+		return 0;
 	}
-	return (ret);
+
+	device_printf(sc->vmbus_dev, "failed to open chan%u\n",
+	    new_channel->ch_id);
+	ret = ENXIO;
+
+failed:
+	atomic_clear_int(&new_channel->ch_stflags, VMBUS_CHAN_ST_OPENED);
+	return ret;
 }
 
 /**
@@ -487,7 +485,9 @@ hv_vmbus_channel_close_internal(hv_vmbus
 	struct taskqueue *rxq = channel->rxq;
 	int error;
 
-	channel->state = HV_CHANNEL_OPEN_STATE;
+	/* TODO: stringent check */
+	atomic_clear_int(&channel->ch_stflags, VMBUS_CHAN_ST_OPENED);
+
 	sysctl_ctx_free(&channel->ch_sysctl_ctx);
 
 	/*
@@ -563,7 +563,7 @@ hv_vmbus_channel_close(hv_vmbus_channel 
 	 */
 	TAILQ_FOREACH(sub_channel, &channel->sc_list_anchor,
 	    sc_list_entry) {
-		if (sub_channel->state != HV_CHANNEL_OPENED_STATE)
+		if ((sub_channel->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0)
 			continue;
 		hv_vmbus_channel_close_internal(sub_channel);
 	}

Modified: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c	Thu Jul 14 06:48:24 2016	(r302811)
+++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c	Thu Jul 14 06:59:04 2016	(r302812)
@@ -191,8 +191,6 @@ vmbus_chan_add(hv_vmbus_channel *new_cha
 			    ch_link);
 			mtx_unlock(&sc->vmbus_chlist_lock);
 
-			new_channel->state = HV_CHANNEL_OPEN_STATE;
-
 			/*
 			 * Bump up sub-channel count and notify anyone that is
 			 * interested in this sub-channel, after this sub-channel
@@ -210,8 +208,6 @@ vmbus_chan_add(hv_vmbus_channel *new_cha
 		    new_channel->ch_id);
 		return EINVAL;
 	}
-
-	new_channel->state = HV_CHANNEL_OPEN_STATE;
 	return 0;
 }
 
@@ -479,7 +475,7 @@ vmbus_select_outgoing_channel(struct hv_
 	cur_vcpu = VMBUS_PCPU_GET(primary->vmbus_sc, vcpuid, smp_pro_id);
 	
 	TAILQ_FOREACH(new_channel, &primary->sc_list_anchor, sc_list_entry) {
-		if (new_channel->state != HV_CHANNEL_OPENED_STATE){
+		if ((new_channel->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0) {
 			continue;
 		}
 

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Thu Jul 14 06:48:24 2016	(r302811)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Thu Jul 14 06:59:04 2016	(r302812)
@@ -55,7 +55,6 @@ typedef struct {
 
 typedef struct {
 	uint32_t 		rel_id;
-	hv_vmbus_channel_state	state;
 	struct hyperv_guid	interface_type;
 	struct hyperv_guid	interface_instance;
 	uint32_t		monitor_id;


More information about the svn-src-head mailing list