svn commit: r307018 - in stable/10/sys: conf dev/hyperv/include dev/hyperv/netvsc dev/hyperv/storvsc dev/hyperv/vmbus modules/hyperv/netvsc modules/hyperv/storvsc modules/hyperv/vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Tue Oct 11 06:35:31 UTC 2016
Author: sephe
Date: Tue Oct 11 06:35:29 2016
New Revision: 307018
URL: https://svnweb.freebsd.org/changeset/base/307018
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.
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/10/sys/dev/hyperv/vmbus/vmbus_if.m
- copied unchanged from r302629, head/sys/dev/hyperv/vmbus/vmbus_if.m
Modified:
stable/10/sys/conf/files.amd64
stable/10/sys/conf/files.i386
stable/10/sys/dev/hyperv/include/hyperv.h
stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
stable/10/sys/dev/hyperv/vmbus/hv_channel.c
stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
stable/10/sys/dev/hyperv/vmbus/hv_connection.c
stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
stable/10/sys/dev/hyperv/vmbus/hyperv.c
stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h
stable/10/sys/dev/hyperv/vmbus/hyperv_var.h
stable/10/sys/dev/hyperv/vmbus/vmbus.c
stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h
stable/10/sys/dev/hyperv/vmbus/vmbus_var.h
stable/10/sys/modules/hyperv/netvsc/Makefile
stable/10/sys/modules/hyperv/storvsc/Makefile
stable/10/sys/modules/hyperv/vmbus/Makefile
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/conf/files.amd64
==============================================================================
--- stable/10/sys/conf/files.amd64 Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/conf/files.amd64 Tue Oct 11 06:35:29 2016 (r307018)
@@ -279,6 +279,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/lindev/full.c optional lindev
Modified: stable/10/sys/conf/files.i386
==============================================================================
--- stable/10/sys/conf/files.i386 Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/conf/files.i386 Tue Oct 11 06:35:29 2016 (r307018)
@@ -256,6 +256,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/10/sys/dev/hyperv/include/hyperv.h
==============================================================================
--- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 06:35:29 2016 (r307018)
@@ -55,6 +55,7 @@
#include <amd64/include/xen/synch_bitops.h>
#include <amd64/include/atomic.h>
+#include <dev/hyperv/include/hyperv_busdma.h>
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/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 06:35:29 2016 (r307018)
@@ -116,9 +116,11 @@ __FBSDID("$FreeBSD$");
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/include/hyperv_busdma.h>
+
#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
@@ -2425,8 +2427,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;
@@ -2465,10 +2469,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
@@ -2476,7 +2488,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 */
@@ -2493,7 +2505,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;
}
@@ -2512,7 +2524,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;
}
@@ -2529,7 +2541,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;
}
@@ -2540,7 +2552,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);
@@ -2551,7 +2563,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);
@@ -2579,7 +2591,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/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Oct 11 06:35:29 2016 (r307018)
@@ -72,7 +72,9 @@ __FBSDID("$FreeBSD$");
#include <cam/scsi/scsi_message.h>
#include <dev/hyperv/include/hyperv.h>
+
#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/10/sys/dev/hyperv/vmbus/hv_channel.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:35:29 2016 (r307018)
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
+#include <dev/hyperv/vmbus/hyperv_var.h>
#include <dev/hyperv/vmbus/vmbus_reg.h>
#include <dev/hyperv/vmbus/vmbus_var.h>
@@ -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/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 06:35:29 2016 (r307018)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/mutex.h>
+#include <dev/hyperv/include/hyperv_busdma.h>
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
#include <dev/hyperv/vmbus/vmbus_reg.h>
#include <dev/hyperv/vmbus/vmbus_var.h>
@@ -49,18 +50,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
@@ -74,13 +67,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
};
/**
@@ -118,6 +111,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;
@@ -125,7 +119,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.
@@ -135,8 +129,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 &&
@@ -148,10 +141,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) {
/*
@@ -175,11 +167,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>, "
@@ -232,8 +232,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;
}
@@ -248,61 +248,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);
}
/**
@@ -338,23 +302,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,
@@ -418,67 +382,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 */
@@ -488,7 +403,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/10/sys/dev/hyperv/vmbus/hv_connection.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_connection.c Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/vmbus/hv_connection.c Tue Oct 11 06:35:29 2016 (r307018)
@@ -50,10 +50,7 @@ __FBSDID("$FreeBSD$");
* 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
@@ -73,10 +70,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);
@@ -161,23 +154,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/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 06:35:29 2016 (r307018)
@@ -38,28 +38,7 @@
#include <dev/hyperv/include/hyperv.h>
-
-/*
- * 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/10/sys/dev/hyperv/vmbus/hyperv.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hyperv.c Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/vmbus/hyperv.c Tue Oct 11 06:35:29 2016 (r307018)
@@ -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/10/sys/dev/hyperv/vmbus/hyperv_reg.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h Tue Oct 11 06:35:29 2016 (r307018)
@@ -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/10/sys/dev/hyperv/vmbus/hyperv_var.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hyperv_var.h Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/vmbus/hyperv_var.h Tue Oct 11 06:35:29 2016 (r307018)
@@ -41,5 +41,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/10/sys/dev/hyperv/vmbus/vmbus.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 06:19:06 2016 (r307017)
+++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 06:35:29 2016 (r307018)
@@ -68,12 +68,9 @@ __FBSDID("$FreeBSD$");
#include <contrib/dev/acpica/include/acpi.h>
#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(rsvd), 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
};
static struct vmbus_msghc *
@@ -378,21 +374,26 @@ vmbus_msghc_wakeup(struct vmbus_softc *s
wakeup(&mhc->mhc_active);
}
+uint32_t
+vmbus_gpadl_alloc(struct vmbus_softc *sc)
+{
+ return atomic_fetchadd_int(&sc->vmbus_gpadl, 1);
+}
+
static int
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable
mailing list