From owner-svn-src-all@freebsd.org Fri Oct 14 08:02:40 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 91734C11BB3; Fri, 14 Oct 2016 08:02:40 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5432BFC1; Fri, 14 Oct 2016 08:02:40 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E82dNO081739; Fri, 14 Oct 2016 08:02:39 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E82cjl081723; Fri, 14 Oct 2016 08:02:38 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140802.u9E82cjl081723@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 08:02:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r307302 - in stable/11/sys: conf dev/hyperv/include dev/hyperv/netvsc dev/hyperv/storvsc dev/hyperv/vmbus modules/hyperv/netvsc modules/hyperv/storvsc modules/hyperv/vmbus X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 08:02:40 -0000 Author: sephe Date: Fri Oct 14 08:02:37 2016 New Revision: 307302 URL: https://svnweb.freebsd.org/changeset/base/307302 Log: MFC 302617-302621,302623,302629-302631 302617 hyperv/vmbus: Flatten channel message response processing. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6914 302618 hyperv/vmbus: Avoid tx_evtflags setting code duplication. MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6915 302619 hyperv/vmbus: Busdma-fy Hypercall signal event input parameter. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6916 302620 hyperv: Nuke unused stuffs Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6917 302621 hyperv/vmbus: Don't be oversmart in default cpu selection. Pin the channel to cpu0 by default. Drivers having special channel-cpu mapping requirement should call vmbus_channel_cpu_{set,rr}() themselves. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6918 302623 hyperv/vmbus: Minor renaming Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6919 302629 hyperv/vmbus: Rework vmbus version accessing. Instead of global variable, vmbus version is accessed through a vmbus DEVMETHOD now. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6953 302630 hyperv/vmbus: Move GPADL index into vmbus_softc Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6954 302631 hyperv/vmbus: Move channel list to vmbus_softc Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6956 Added: stable/11/sys/dev/hyperv/vmbus/vmbus_if.m - copied unchanged from r302629, head/sys/dev/hyperv/vmbus/vmbus_if.m Modified: stable/11/sys/conf/files.amd64 stable/11/sys/conf/files.i386 stable/11/sys/dev/hyperv/include/hyperv.h stable/11/sys/dev/hyperv/include/hyperv_busdma.h stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/11/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/11/sys/dev/hyperv/vmbus/hv_channel.c stable/11/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/11/sys/dev/hyperv/vmbus/hv_connection.c stable/11/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/11/sys/dev/hyperv/vmbus/hyperv.c stable/11/sys/dev/hyperv/vmbus/hyperv_reg.h stable/11/sys/dev/hyperv/vmbus/hyperv_var.h stable/11/sys/dev/hyperv/vmbus/vmbus.c stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h stable/11/sys/dev/hyperv/vmbus/vmbus_var.h stable/11/sys/modules/hyperv/netvsc/Makefile stable/11/sys/modules/hyperv/storvsc/Makefile stable/11/sys/modules/hyperv/vmbus/Makefile Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/conf/files.amd64 ============================================================================== --- stable/11/sys/conf/files.amd64 Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/conf/files.amd64 Fri Oct 14 08:02:37 2016 (r307302) @@ -309,6 +309,7 @@ dev/hyperv/vmbus/hyperv.c optional hy dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv +dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/amd64/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/amd64/vmbus_vector.S optional hyperv dev/nfe/if_nfe.c optional nfe pci Modified: stable/11/sys/conf/files.i386 ============================================================================== --- stable/11/sys/conf/files.i386 Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/conf/files.i386 Fri Oct 14 08:02:37 2016 (r307302) @@ -266,6 +266,7 @@ dev/hyperv/vmbus/hyperv.c optional hy dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv +dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/i386/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/i386/vmbus_vector.S optional hyperv dev/ichwd/ichwd.c optional ichwd Modified: stable/11/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/11/sys/dev/hyperv/include/hyperv.h Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/include/hyperv.h Fri Oct 14 08:02:37 2016 (r307302) @@ -55,6 +55,7 @@ #include #include +#include typedef uint8_t hv_bool_uint8_t; @@ -72,10 +73,13 @@ typedef uint8_t hv_bool_uint8_t; * 2.4 -- Windows 8 * 3.0 -- Windows 8.1 */ -#define HV_VMBUS_VERSION_WS2008 ((0 << 16) | (13)) -#define HV_VMBUS_VERSION_WIN7 ((1 << 16) | (1)) -#define HV_VMBUS_VERSION_WIN8 ((2 << 16) | (4)) -#define HV_VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) +#define VMBUS_VERSION_WS2008 ((0 << 16) | (13)) +#define VMBUS_VERSION_WIN7 ((1 << 16) | (1)) +#define VMBUS_VERSION_WIN8 ((2 << 16) | (4)) +#define VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) + +#define VMBUS_VERSION_MAJOR(ver) (((uint32_t)(ver)) >> 16) +#define VMBUS_VERSION_MINOR(ver) (((uint32_t)(ver)) & 0xffff) /* * Make maximum size of pipe payload of 16K @@ -528,22 +532,7 @@ typedef union { } __packed hv_vmbus_connection_id; -/* - * Definition of the hv_vmbus_signal_event hypercall input structure - */ -typedef struct { - hv_vmbus_connection_id connection_id; - uint16_t flag_number; - uint16_t rsvd_z; -} __packed hv_vmbus_input_signal_event; - -typedef struct { - uint64_t align8; - hv_vmbus_input_signal_event event; -} __packed hv_vmbus_input_signal_event_buffer; - typedef struct hv_vmbus_channel { - TAILQ_ENTRY(hv_vmbus_channel) list_entry; struct hv_device* device; struct vmbus_softc *vmbus_sc; hv_vmbus_channel_state state; @@ -589,14 +578,8 @@ typedef struct hv_vmbus_channel { boolean_t is_dedicated_interrupt; - /* - * Used as an input param for HV_CALL_SIGNAL_EVENT hypercall. - */ - hv_vmbus_input_signal_event_buffer signal_event_buffer; - /* - * 8-bytes aligned of the buffer above - */ - hv_vmbus_input_signal_event *signal_event_param; + struct hypercall_sigevt_in *ch_sigevt; + struct hyperv_dma ch_sigevt_dma; /* * From Win8, this field specifies the target virtual process @@ -643,6 +626,7 @@ typedef struct hv_vmbus_channel { void *hv_chan_priv3; struct task ch_detach_task; + TAILQ_ENTRY(hv_vmbus_channel) ch_link; } hv_vmbus_channel; #define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL) @@ -726,6 +710,7 @@ int hv_vmbus_channel_teardown_gpdal( struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary); void vmbus_channel_cpu_set(struct hv_vmbus_channel *chan, int cpu); +void vmbus_channel_cpu_rr(struct hv_vmbus_channel *chan); struct hv_vmbus_channel ** vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt); void vmbus_rel_subchan(struct hv_vmbus_channel **subchan, int subchan_cnt); @@ -741,5 +726,4 @@ hv_get_phys_addr(void *virt) return (ret); } -extern uint32_t hv_vmbus_protocal_version; #endif /* __HYPERV_H__ */ Modified: stable/11/sys/dev/hyperv/include/hyperv_busdma.h ============================================================================== --- stable/11/sys/dev/hyperv/include/hyperv_busdma.h Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/include/hyperv_busdma.h Fri Oct 14 08:02:37 2016 (r307302) @@ -29,6 +29,10 @@ #ifndef _HYPERV_BUSDMA_H_ #define _HYPERV_BUSDMA_H_ +#include +#include +#include + struct hyperv_dma { bus_addr_t hv_paddr; bus_dma_tag_t hv_dtag; Modified: stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 08:02:37 2016 (r307302) @@ -114,9 +114,11 @@ __FBSDID("$FreeBSD$"); #include #include + #include "hv_net_vsc.h" #include "hv_rndis.h" #include "hv_rndis_filter.h" +#include "vmbus_if.h" #define hv_chan_rxr hv_chan_priv1 #define hv_chan_txr hv_chan_priv2 @@ -2369,8 +2371,10 @@ static int hn_create_tx_ring(struct hn_softc *sc, int id) { struct hn_tx_ring *txr = &sc->hn_tx_ring[id]; + device_t dev = sc->hn_dev; bus_dma_tag_t parent_dtag; int error, i; + uint32_t version; txr->hn_sc = sc; txr->hn_tx_idx = id; @@ -2409,10 +2413,18 @@ hn_create_tx_ring(struct hn_softc *sc, i } txr->hn_direct_tx_size = hn_direct_tx_size; - if (hv_vmbus_protocal_version >= HV_VMBUS_VERSION_WIN8_1) + version = VMBUS_GET_VERSION(device_get_parent(dev), dev); + if (version >= VMBUS_VERSION_WIN8_1) { txr->hn_csum_assist = HN_CSUM_ASSIST; - else + } else { txr->hn_csum_assist = HN_CSUM_ASSIST_WIN8; + if (id == 0) { + device_printf(dev, "bus version %u.%u, " + "no UDP checksum offloading\n", + VMBUS_VERSION_MAJOR(version), + VMBUS_VERSION_MINOR(version)); + } + } /* * Always schedule transmission instead of trying to do direct @@ -2420,7 +2432,7 @@ hn_create_tx_ring(struct hn_softc *sc, i */ txr->hn_sched_tx = 1; - parent_dtag = bus_get_dma_tag(sc->hn_dev); + parent_dtag = bus_get_dma_tag(dev); /* DMA tag for RNDIS messages. */ error = bus_dma_tag_create(parent_dtag, /* parent */ @@ -2437,7 +2449,7 @@ hn_create_tx_ring(struct hn_softc *sc, i NULL, /* lockfuncarg */ &txr->hn_tx_rndis_dtag); if (error) { - device_printf(sc->hn_dev, "failed to create rndis dmatag\n"); + device_printf(dev, "failed to create rndis dmatag\n"); return error; } @@ -2456,7 +2468,7 @@ hn_create_tx_ring(struct hn_softc *sc, i NULL, /* lockfuncarg */ &txr->hn_tx_data_dtag); if (error) { - device_printf(sc->hn_dev, "failed to create data dmatag\n"); + device_printf(dev, "failed to create data dmatag\n"); return error; } @@ -2473,7 +2485,7 @@ hn_create_tx_ring(struct hn_softc *sc, i BUS_DMA_WAITOK | BUS_DMA_COHERENT, &txd->rndis_msg_dmap); if (error) { - device_printf(sc->hn_dev, + device_printf(dev, "failed to allocate rndis_msg, %d\n", i); return error; } @@ -2484,7 +2496,7 @@ hn_create_tx_ring(struct hn_softc *sc, i hyperv_dma_map_paddr, &txd->rndis_msg_paddr, BUS_DMA_NOWAIT); if (error) { - device_printf(sc->hn_dev, + device_printf(dev, "failed to load rndis_msg, %d\n", i); bus_dmamem_free(txr->hn_tx_rndis_dtag, txd->rndis_msg, txd->rndis_msg_dmap); @@ -2495,7 +2507,7 @@ hn_create_tx_ring(struct hn_softc *sc, i error = bus_dmamap_create(txr->hn_tx_data_dtag, 0, &txd->data_dmap); if (error) { - device_printf(sc->hn_dev, + device_printf(dev, "failed to allocate tx data dmamap\n"); bus_dmamap_unload(txr->hn_tx_rndis_dtag, txd->rndis_msg_dmap); @@ -2523,7 +2535,7 @@ hn_create_tx_ring(struct hn_softc *sc, i * Create per TX ring sysctl tree: * dev.hn.UNIT.tx.RINGID */ - ctx = device_get_sysctl_ctx(sc->hn_dev); + ctx = device_get_sysctl_ctx(dev); child = SYSCTL_CHILDREN(sc->hn_tx_sysctl_tree); snprintf(name, sizeof(name), "%d", id); Modified: stable/11/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/11/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Fri Oct 14 08:02:37 2016 (r307302) @@ -72,7 +72,9 @@ __FBSDID("$FreeBSD$"); #include #include + #include "hv_vstorage.h" +#include "vmbus_if.h" #define STORVSC_RINGBUFFER_SIZE (20*PAGE_SIZE) #define STORVSC_MAX_LUNS_PER_TARGET (64) @@ -361,6 +363,7 @@ storvsc_subchan_attach(struct hv_vmbus_c memset(&props, 0, sizeof(props)); + vmbus_channel_cpu_rr(new_channel); ret = hv_vmbus_channel_open(new_channel, sc->hs_drv_props->drv_ringbuffer_size, sc->hs_drv_props->drv_ringbuffer_size, @@ -464,6 +467,7 @@ hv_storvsc_channel_init(struct hv_device struct storvsc_softc *sc; uint16_t max_chans = 0; boolean_t support_multichannel = FALSE; + uint32_t version; max_chans = 0; support_multichannel = FALSE; @@ -588,8 +592,9 @@ hv_storvsc_channel_init(struct hv_device /* multi-channels feature is supported by WIN8 and above version */ max_chans = vstor_packet->u.chan_props.max_channel_cnt; - if ((hv_vmbus_protocal_version != HV_VMBUS_VERSION_WIN7) && - (hv_vmbus_protocal_version != HV_VMBUS_VERSION_WS2008) && + version = VMBUS_GET_VERSION(device_get_parent(dev->device), + dev->device); + if (version != VMBUS_VERSION_WIN7 && version != VMBUS_VERSION_WS2008 && (vstor_packet->u.chan_props.flags & HV_STORAGE_SUPPORTS_MULTI_CHANNEL)) { support_multichannel = TRUE; @@ -655,7 +660,7 @@ hv_storvsc_connect_vsp(struct hv_device /* * Open the channel */ - + vmbus_channel_cpu_rr(dev->channel); ret = hv_vmbus_channel_open( dev->channel, sc->hs_drv_props->drv_ringbuffer_size, Modified: stable/11/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/11/sys/dev/hyperv/vmbus/hv_channel.c Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/vmbus/hv_channel.c Fri Oct 14 08:02:37 2016 (r307302) @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -58,21 +59,21 @@ static void VmbusProcessChannelEvent(voi static void vmbus_channel_set_event(hv_vmbus_channel *channel) { + struct vmbus_softc *sc = channel->vmbus_sc; + uint32_t chanid = channel->offer_msg.child_rel_id; + + atomic_set_long(&sc->vmbus_tx_evtflags[chanid >> VMBUS_EVTFLAG_SHIFT], + 1UL << (chanid & VMBUS_EVTFLAG_MASK)); + if (channel->offer_msg.monitor_allocated) { - struct vmbus_softc *sc = channel->vmbus_sc; hv_vmbus_monitor_page *monitor_page; - uint32_t chanid = channel->offer_msg.child_rel_id; - - atomic_set_long( - &sc->vmbus_tx_evtflags[chanid >> VMBUS_EVTFLAG_SHIFT], - 1UL << (chanid & VMBUS_EVTFLAG_MASK)); monitor_page = sc->vmbus_mnf2; synch_set_bit(channel->monitor_bit, (uint32_t *)&monitor_page-> trigger_group[channel->monitor_group].u.pending); } else { - hv_vmbus_set_event(channel); + hypercall_signal_event(channel->ch_sigevt_dma.hv_paddr); } } @@ -342,8 +343,7 @@ hv_vmbus_channel_establish_gpadl(struct /* * Allocate GPADL id. */ - gpadl = atomic_fetchadd_int( - &hv_vmbus_g_connection.next_gpadl_handle, 1); + gpadl = vmbus_gpadl_alloc(sc); *gpadl0 = gpadl; /* Modified: stable/11/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/11/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Fri Oct 14 08:02:37 2016 (r307302) @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -46,18 +47,10 @@ static void vmbus_chan_detach_task(void static void vmbus_channel_on_offer(struct vmbus_softc *, const struct vmbus_message *); -static void vmbus_channel_on_open_result(struct vmbus_softc *, - const struct vmbus_message *); static void vmbus_channel_on_offer_rescind(struct vmbus_softc *, const struct vmbus_message *); -static void vmbus_channel_on_gpadl_created(struct vmbus_softc *, - const struct vmbus_message *); -static void vmbus_channel_on_gpadl_torndown(struct vmbus_softc *, - const struct vmbus_message *); static void vmbus_channel_on_offers_delivered(struct vmbus_softc *, const struct vmbus_message *); -static void vmbus_channel_on_version_response(struct vmbus_softc *, - const struct vmbus_message *); /** * Channel message dispatch table @@ -71,13 +64,13 @@ vmbus_chanmsg_process[HV_CHANNEL_MESSAGE [HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED] = vmbus_channel_on_offers_delivered, [HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT] = - vmbus_channel_on_open_result, + vmbus_msghc_wakeup, [HV_CHANNEL_MESSAGE_GPADL_CREATED] = - vmbus_channel_on_gpadl_created, + vmbus_msghc_wakeup, [HV_CHANNEL_MESSAGE_GPADL_TORNDOWN] = - vmbus_channel_on_gpadl_torndown, + vmbus_msghc_wakeup, [HV_CHANNEL_MESSAGE_VERSION_RESPONSE] = - vmbus_channel_on_version_response + vmbus_msghc_wakeup }; /** @@ -115,6 +108,7 @@ hv_vmbus_free_vmbus_channel(hv_vmbus_cha static void vmbus_channel_process_offer(hv_vmbus_channel *new_channel) { + struct vmbus_softc *sc = new_channel->vmbus_sc; hv_vmbus_channel* channel; uint32_t relid; @@ -122,7 +116,7 @@ vmbus_channel_process_offer(hv_vmbus_cha /* * Make sure this is a new offer */ - mtx_lock(&hv_vmbus_g_connection.channel_lock); + mtx_lock(&sc->vmbus_chlist_lock); if (relid == 0) { /* * XXX channel0 will not be processed; skip it. @@ -132,8 +126,7 @@ vmbus_channel_process_offer(hv_vmbus_cha hv_vmbus_g_connection.channels[relid] = new_channel; } - TAILQ_FOREACH(channel, &hv_vmbus_g_connection.channel_anchor, - list_entry) { + TAILQ_FOREACH(channel, &sc->vmbus_chlist, ch_link) { if (memcmp(&channel->offer_msg.offer.interface_type, &new_channel->offer_msg.offer.interface_type, sizeof(hv_guid)) == 0 && @@ -145,10 +138,9 @@ vmbus_channel_process_offer(hv_vmbus_cha if (channel == NULL) { /* Install the new primary channel */ - TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_anchor, - new_channel, list_entry); + TAILQ_INSERT_TAIL(&sc->vmbus_chlist, new_channel, ch_link); } - mtx_unlock(&hv_vmbus_g_connection.channel_lock); + mtx_unlock(&sc->vmbus_chlist_lock); if (channel != NULL) { /* @@ -172,11 +164,19 @@ vmbus_channel_process_offer(hv_vmbus_cha new_channel->offer_msg.offer.sub_channel_index); } - /* Insert new channel into channel_anchor. */ - mtx_lock(&hv_vmbus_g_connection.channel_lock); - TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_anchor, - new_channel, list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_lock); + /* + * Insert the new channel to the end of the global + * channel list. + * + * NOTE: + * The new sub-channel MUST be inserted AFTER it's + * primary channel, so that the primary channel will + * be found in the above loop for its baby siblings. + */ + mtx_lock(&sc->vmbus_chlist_lock); + TAILQ_INSERT_TAIL(&sc->vmbus_chlist, new_channel, + ch_link); + mtx_unlock(&sc->vmbus_chlist_lock); if(bootverbose) printf("VMBUS: new multi-channel offer <%p>, " @@ -229,8 +229,8 @@ vmbus_channel_cpu_set(struct hv_vmbus_ch { KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpu %d", cpu)); - if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 || - hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7) { + if (chan->vmbus_sc->vmbus_version == VMBUS_VERSION_WS2008 || + chan->vmbus_sc->vmbus_version == VMBUS_VERSION_WIN7) { /* Only cpu0 is supported */ cpu = 0; } @@ -245,61 +245,25 @@ vmbus_channel_cpu_set(struct hv_vmbus_ch } } -/** - * Array of device guids that are performance critical. We try to distribute - * the interrupt load for these devices across all online cpus. - */ -static const hv_guid high_perf_devices[] = { - {HV_NIC_GUID, }, - {HV_IDE_GUID, }, - {HV_SCSI_GUID, }, -}; - -enum { - PERF_CHN_NIC = 0, - PERF_CHN_IDE, - PERF_CHN_SCSI, - MAX_PERF_CHN, -}; +void +vmbus_channel_cpu_rr(struct hv_vmbus_channel *chan) +{ + static uint32_t vmbus_chan_nextcpu; + int cpu; -/* - * We use this static number to distribute the channel interrupt load. - */ -static uint32_t next_vcpu; + cpu = atomic_fetchadd_int(&vmbus_chan_nextcpu, 1) % mp_ncpus; + vmbus_channel_cpu_set(chan, cpu); +} -/** - * Starting with Win8, we can statically distribute the incoming - * channel interrupt load by binding a channel to VCPU. We - * implement here a simple round robin scheme for distributing - * the interrupt load. - * We will bind channels that are not performance critical to cpu 0 and - * performance critical channels (IDE, SCSI and Network) will be uniformly - * distributed across all available CPUs. - */ static void -vmbus_channel_select_defcpu(struct hv_vmbus_channel *channel) +vmbus_channel_select_defcpu(struct hv_vmbus_channel *chan) { - uint32_t current_cpu; - int i; - boolean_t is_perf_channel = FALSE; - const hv_guid *guid = &channel->offer_msg.offer.interface_type; - - for (i = PERF_CHN_NIC; i < MAX_PERF_CHN; i++) { - if (memcmp(guid->data, high_perf_devices[i].data, - sizeof(hv_guid)) == 0) { - is_perf_channel = TRUE; - break; - } - } - - if (!is_perf_channel) { - /* Stick to cpu0 */ - vmbus_channel_cpu_set(channel, 0); - return; - } - /* mp_ncpus should have the number cpus currently online */ - current_cpu = (++next_vcpu % mp_ncpus); - vmbus_channel_cpu_set(channel, current_cpu); + /* + * By default, pin the channel to cpu0. Devices having + * special channel-cpu mapping requirement should call + * vmbus_channel_cpu_{set,rr}(). + */ + vmbus_channel_cpu_set(chan, 0); } /** @@ -335,23 +299,23 @@ vmbus_channel_on_offer_internal(struct v */ new_channel->batched_reading = TRUE; - new_channel->signal_event_param = - (hv_vmbus_input_signal_event *) - (HV_ALIGN_UP((unsigned long) - &new_channel->signal_event_buffer, - HV_HYPERCALL_PARAM_ALIGN)); - - new_channel->signal_event_param->connection_id.as_uint32_t = 0; - new_channel->signal_event_param->connection_id.u.id = - HV_VMBUS_EVENT_CONNECTION_ID; - new_channel->signal_event_param->flag_number = 0; - new_channel->signal_event_param->rsvd_z = 0; + new_channel->ch_sigevt = hyperv_dmamem_alloc( + bus_get_dma_tag(sc->vmbus_dev), + HYPERCALL_SIGEVTIN_ALIGN, 0, sizeof(struct hypercall_sigevt_in), + &new_channel->ch_sigevt_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (new_channel->ch_sigevt == NULL) { + device_printf(sc->vmbus_dev, "sigevt alloc failed\n"); + /* XXX */ + mtx_destroy(&new_channel->sc_lock); + free(new_channel, M_DEVBUF); + return; + } + new_channel->ch_sigevt->hc_connid = VMBUS_CONNID_EVENT; - if (hv_vmbus_protocal_version != HV_VMBUS_VERSION_WS2008) { + if (sc->vmbus_version != VMBUS_VERSION_WS2008) { new_channel->is_dedicated_interrupt = (offer->is_dedicated_interrupt != 0); - new_channel->signal_event_param->connection_id.u.id = - offer->connection_id; + new_channel->ch_sigevt->hc_connid = offer->connection_id; } memcpy(&new_channel->offer_msg, offer, @@ -415,67 +379,18 @@ vmbus_channel_on_offers_delivered(struct } /** - * @brief Open result handler. - * - * This is invoked when we received a response - * to our channel open request. - */ -static void -vmbus_channel_on_open_result(struct vmbus_softc *sc, - const struct vmbus_message *msg) -{ - vmbus_msghc_wakeup(sc, msg); -} - -/** - * @brief GPADL created handler. - * - * This is invoked when we received a response - * to our gpadl create request. Find the matching request, copy the - * response and signal the requesting thread. - */ -static void -vmbus_channel_on_gpadl_created(struct vmbus_softc *sc, - const struct vmbus_message *msg) -{ - vmbus_msghc_wakeup(sc, msg); -} - -/** - * @brief GPADL torndown handler. - * - * This is invoked when we received a respons - * to our gpadl teardown request. Find the matching request, copy the - * response and signal the requesting thread - */ -static void -vmbus_channel_on_gpadl_torndown(struct vmbus_softc *sc, - const struct vmbus_message *msg) -{ - vmbus_msghc_wakeup(sc, msg); -} - -static void -vmbus_channel_on_version_response(struct vmbus_softc *sc, - const struct vmbus_message *msg) -{ - vmbus_msghc_wakeup(sc, msg); -} - -/** * @brief Release channels that are unattached/unconnected (i.e., no drivers associated) */ void -hv_vmbus_release_unattached_channels(void) +hv_vmbus_release_unattached_channels(struct vmbus_softc *sc) { hv_vmbus_channel *channel; - mtx_lock(&hv_vmbus_g_connection.channel_lock); + mtx_lock(&sc->vmbus_chlist_lock); - while (!TAILQ_EMPTY(&hv_vmbus_g_connection.channel_anchor)) { - channel = TAILQ_FIRST(&hv_vmbus_g_connection.channel_anchor); - TAILQ_REMOVE(&hv_vmbus_g_connection.channel_anchor, - channel, list_entry); + while (!TAILQ_EMPTY(&sc->vmbus_chlist)) { + channel = TAILQ_FIRST(&sc->vmbus_chlist); + TAILQ_REMOVE(&sc->vmbus_chlist, channel, ch_link); if (HV_VMBUS_CHAN_ISPRIMARY(channel)) { /* Only primary channel owns the hv_device */ @@ -485,7 +400,8 @@ hv_vmbus_release_unattached_channels(voi } bzero(hv_vmbus_g_connection.channels, sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX); - mtx_unlock(&hv_vmbus_g_connection.channel_lock); + + mtx_unlock(&sc->vmbus_chlist_lock); } /** Modified: stable/11/sys/dev/hyperv/vmbus/hv_connection.c ============================================================================== --- stable/11/sys/dev/hyperv/vmbus/hv_connection.c Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/vmbus/hv_connection.c Fri Oct 14 08:02:37 2016 (r307302) @@ -47,10 +47,7 @@ * Globals */ hv_vmbus_connection hv_vmbus_g_connection = - { .connect_state = HV_DISCONNECTED, - .next_gpadl_handle = 0xE1E10, }; - -uint32_t hv_vmbus_protocal_version; + { .connect_state = HV_DISCONNECTED }; /** * Send a connect request on the partition service connection @@ -70,10 +67,6 @@ hv_vmbus_connect(struct vmbus_softc *sc) */ hv_vmbus_g_connection.connect_state = HV_CONNECTING; - TAILQ_INIT(&hv_vmbus_g_connection.channel_anchor); - mtx_init(&hv_vmbus_g_connection.channel_lock, "vmbus channel", - NULL, MTX_DEF); - hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO); @@ -158,23 +151,6 @@ vmbus_event_proc_compat(struct vmbus_sof } } -/** - * Send an event notification to the parent - */ -int -hv_vmbus_set_event(hv_vmbus_channel *channel) -{ - struct vmbus_softc *sc = channel->vmbus_sc; - int ret = 0; - uint32_t chanid = channel->offer_msg.child_rel_id; - - atomic_set_long(&sc->vmbus_tx_evtflags[chanid >> VMBUS_EVTFLAG_SHIFT], - 1UL << (chanid & VMBUS_EVTFLAG_MASK)); - ret = hv_vmbus_signal_event(channel->signal_event_param); - - return (ret); -} - void vmbus_on_channel_open(const struct hv_vmbus_channel *chan) { Modified: stable/11/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/11/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Fri Oct 14 08:02:37 2016 (r307302) @@ -38,28 +38,7 @@ #include - -/* - * Status codes for hypervisor operations. - */ - -typedef uint16_t hv_vmbus_status; - -#define HV_MESSAGE_SIZE (256) -#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240) -#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30) -#define HV_ANY_VP (0xFFFFFFFF) - -/* - * MessageId: HV_STATUS_INSUFFICIENT_BUFFERS - * MessageText: - * You did not supply enough message buffers to send a message. - */ - -#define HV_STATUS_SUCCESS ((uint16_t)0) -#define HV_STATUS_INSUFFICIENT_BUFFERS ((uint16_t)0x0013) - -typedef void (*hv_vmbus_channel_callback)(void *context); +struct vmbus_softc; typedef struct { void* data; @@ -118,74 +97,6 @@ typedef struct hv_vmbus_channel_packet_m hv_vmbus_multipage_buffer range; } __packed hv_vmbus_channel_packet_multipage_buffer; -enum { - HV_VMBUS_MESSAGE_CONNECTION_ID = 1, - HV_VMBUS_MESSAGE_PORT_ID = 1, - HV_VMBUS_EVENT_CONNECTION_ID = 2, - HV_VMBUS_EVENT_PORT_ID = 2, - HV_VMBUS_MONITOR_CONNECTION_ID = 3, - HV_VMBUS_MONITOR_PORT_ID = 3, -}; - -#define HV_PRESENT_BIT 0x80000000 - -#define HV_HYPERCALL_PARAM_ALIGN sizeof(uint64_t) - -/* - * Define hypervisor message types - */ -typedef enum { - - HV_MESSAGE_TYPE_NONE = 0x00000000, - - /* - * Memory access messages - */ - HV_MESSAGE_TYPE_UNMAPPED_GPA = 0x80000000, - HV_MESSAGE_TYPE_GPA_INTERCEPT = 0x80000001, - - /* - * Timer notification messages - */ - HV_MESSAGE_TIMER_EXPIRED = 0x80000010, - - /* - * Error messages - */ - HV_MESSAGE_TYPE_INVALID_VP_REGISTER_VALUE = 0x80000020, - HV_MESSAGE_TYPE_UNRECOVERABLE_EXCEPTION = 0x80000021, - HV_MESSAGE_TYPE_UNSUPPORTED_FEATURE = 0x80000022, - - /* - * Trace buffer complete messages - */ - HV_MESSAGE_TYPE_EVENT_LOG_BUFFER_COMPLETE = 0x80000040, - - /* - * Platform-specific processor intercept messages - */ - HV_MESSAGE_TYPE_X64_IO_PORT_INTERCEPT = 0x80010000, - HV_MESSAGE_TYPE_X64_MSR_INTERCEPT = 0x80010001, - HV_MESSAGE_TYPE_X64_CPU_INTERCEPT = 0x80010002, - HV_MESSAGE_TYPE_X64_EXCEPTION_INTERCEPT = 0x80010003, - HV_MESSAGE_TYPE_X64_APIC_EOI = 0x80010004, - HV_MESSAGE_TYPE_X64_LEGACY_FP_ERROR = 0x80010005 - -} hv_vmbus_msg_type; - -/* - * Define port identifier type - */ -typedef union _hv_vmbus_port_id { - uint32_t as_uint32_t; - struct { - uint32_t id:24; - uint32_t reserved:8; - } u ; -} hv_vmbus_port_id; - -typedef uint64_t hv_vmbus_partition_id; - /* * VM Bus connection states */ @@ -196,19 +107,8 @@ typedef enum { HV_DISCONNECTING } hv_vmbus_connect_state; -#define HV_MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT - - typedef struct { hv_vmbus_connect_state connect_state; - uint32_t next_gpadl_handle; - - /** - * List of primary channels. Sub channels will be linked - * under their primary channel. - */ - TAILQ_HEAD(, hv_vmbus_channel) channel_anchor; - struct mtx channel_lock; /** * channel table for fast lookup through id. @@ -277,14 +177,6 @@ typedef struct { uint8_t rsvd_z4[1984]; } hv_vmbus_monitor_page; -/* - * Declare the various hypercall operations - */ -typedef enum { - HV_CALL_POST_MESSAGE = 0x005c, - HV_CALL_SIGNAL_EVENT = 0x005d, -} hv_vmbus_call_code; - /** * Global variables */ @@ -342,17 +234,14 @@ uint32_t hv_ring_buffer_read_end( hv_vmbus_ring_buffer_info *ring_info); void hv_vmbus_free_vmbus_channel(hv_vmbus_channel *channel); -void hv_vmbus_release_unattached_channels(void); - -uint16_t hv_vmbus_signal_event(void *con_id); +void hv_vmbus_release_unattached_channels( + struct vmbus_softc *); struct hv_device* hv_vmbus_child_device_create( hv_guid device_type, hv_guid device_instance, hv_vmbus_channel *channel); -struct vmbus_softc; - void hv_vmbus_child_device_register(struct vmbus_softc *, struct hv_device *child_dev); int hv_vmbus_child_device_unregister( @@ -363,6 +252,5 @@ int hv_vmbus_child_device_unregister( */ int hv_vmbus_connect(struct vmbus_softc *); int hv_vmbus_disconnect(void); -int hv_vmbus_set_event(hv_vmbus_channel *channel); #endif /* __HYPERV_PRIV_H__ */ Modified: stable/11/sys/dev/hyperv/vmbus/hyperv.c ============================================================================== --- stable/11/sys/dev/hyperv/vmbus/hyperv.c Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/vmbus/hyperv.c Fri Oct 14 08:02:37 2016 (r307302) @@ -101,23 +101,6 @@ hyperv_get_timecount(struct timecounter return rdmsr(MSR_HV_TIME_REF_COUNT); } -/** - * @brief Invoke the specified hypercall - */ -static uint64_t -hv_vmbus_do_hypercall(uint64_t value, void *input, void *output) -{ - uint64_t in_paddr = 0, out_paddr = 0; - - if (input != NULL) - in_paddr = hv_get_phys_addr(input); - if (output != NULL) - out_paddr = hv_get_phys_addr(output); - - return hypercall_md(hypercall_context.hc_addr, value, - in_paddr, out_paddr); -} - uint64_t hypercall_post_message(bus_addr_t msg_paddr) { @@ -125,21 +108,11 @@ hypercall_post_message(bus_addr_t msg_pa HYPERCALL_POST_MESSAGE, msg_paddr, 0); } -/** - * @brief Signal an event on the specified connection using the hypervisor - * event IPC. (This involves a hypercall.) - */ -hv_vmbus_status -hv_vmbus_signal_event(void *con_id) -{ - hv_vmbus_status status; - - status = hv_vmbus_do_hypercall( - HV_CALL_SIGNAL_EVENT, - con_id, - 0) & 0xFFFF; - - return (status); +uint64_t +hypercall_signal_event(bus_addr_t sigevt_paddr) +{ + return hypercall_md(hypercall_context.hc_addr, + HYPERCALL_SIGNAL_EVENT, sigevt_paddr, 0); } int Modified: stable/11/sys/dev/hyperv/vmbus/hyperv_reg.h ============================================================================== --- stable/11/sys/dev/hyperv/vmbus/hyperv_reg.h Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/vmbus/hyperv_reg.h Fri Oct 14 08:02:37 2016 (r307302) @@ -148,6 +148,7 @@ * Hypercall input values */ #define HYPERCALL_POST_MESSAGE 0x005c +#define HYPERCALL_SIGNAL_EVENT 0x005d /* * Hypercall input parameters @@ -169,4 +170,15 @@ struct hypercall_postmsg_in { } __packed; CTASSERT(sizeof(struct hypercall_postmsg_in) == HYPERCALL_POSTMSGIN_SIZE); +/* + * HYPERCALL_SIGNAL_EVENT + */ +#define HYPERCALL_SIGEVTIN_ALIGN 8 + +struct hypercall_sigevt_in { + uint32_t hc_connid; + uint16_t hc_evtflag_ofs; + uint16_t hc_rsvd; +} __packed; + #endif /* !_HYPERV_REG_H_ */ Modified: stable/11/sys/dev/hyperv/vmbus/hyperv_var.h ============================================================================== --- stable/11/sys/dev/hyperv/vmbus/hyperv_var.h Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/vmbus/hyperv_var.h Fri Oct 14 08:02:37 2016 (r307302) @@ -39,5 +39,6 @@ extern u_int hyperv_features; extern u_int hyperv_recommends; uint64_t hypercall_post_message(bus_addr_t msg_paddr); +uint64_t hypercall_signal_event(bus_addr_t sigevt_paddr); #endif /* !_HYPERV_VAR_H_ */ Modified: stable/11/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/11/sys/dev/hyperv/vmbus/vmbus.c Fri Oct 14 07:47:35 2016 (r307301) +++ stable/11/sys/dev/hyperv/vmbus/vmbus.c Fri Oct 14 08:02:37 2016 (r307302) @@ -68,12 +68,9 @@ __FBSDID("$FreeBSD$"); #include #include "acpi_if.h" +#include "vmbus_if.h" -/* - * NOTE: DO NOT CHANGE THESE - */ -#define VMBUS_CONNID_MESSAGE 1 -#define VMBUS_CONNID_EVENT 2 +#define VMBUS_GPADL_START 0xe1e10 struct vmbus_msghc { struct hypercall_postmsg_in *mh_inprm; @@ -96,10 +93,9 @@ struct vmbus_msghc_ctx { #define VMBUS_MSGHC_CTXF_DESTROY 0x0001 static int vmbus_init(struct vmbus_softc *); -static int vmbus_init_contact(struct vmbus_softc *, - uint32_t); +static int vmbus_connect(struct vmbus_softc *, uint32_t); static int vmbus_req_channels(struct vmbus_softc *sc); -static void vmbus_uninit(struct vmbus_softc *); +static void vmbus_disconnect(struct vmbus_softc *); static int vmbus_scan(struct vmbus_softc *); static void vmbus_scan_wait(struct vmbus_softc *); static void vmbus_scan_newdev(struct vmbus_softc *); @@ -120,10 +116,10 @@ struct vmbus_softc *vmbus_sc; extern inthand_t IDTVEC(vmbus_isr); static const uint32_t vmbus_version[] = { - HV_VMBUS_VERSION_WIN8_1, - HV_VMBUS_VERSION_WIN8, - HV_VMBUS_VERSION_WIN7, - HV_VMBUS_VERSION_WS2008 + VMBUS_VERSION_WIN8_1, + VMBUS_VERSION_WIN8, + VMBUS_VERSION_WIN7, + VMBUS_VERSION_WS2008 }; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***