Date: Thu, 14 Jul 2016 06:59:04 +0000 (UTC) From: Sepherosa Ziehau <sephe@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r302812 - in head/sys/dev/hyperv: include netvsc vmbus Message-ID: <201607140659.u6E6x4Eh071856@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607140659.u6E6x4Eh071856>