Date: Tue, 12 Jul 2016 05:31:33 +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: r302621 - in head/sys/dev/hyperv: include storvsc vmbus Message-ID: <201607120531.u6C5VXTS064640@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sephe Date: Tue Jul 12 05:31:33 2016 New Revision: 302621 URL: https://svnweb.freebsd.org/changeset/base/302621 Log: 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. MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6918 Modified: head/sys/dev/hyperv/include/hyperv.h head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Modified: head/sys/dev/hyperv/include/hyperv.h ============================================================================== --- head/sys/dev/hyperv/include/hyperv.h Tue Jul 12 05:23:14 2016 (r302620) +++ head/sys/dev/hyperv/include/hyperv.h Tue Jul 12 05:31:33 2016 (r302621) @@ -707,6 +707,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); Modified: head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Jul 12 05:23:14 2016 (r302620) +++ head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Jul 12 05:31:33 2016 (r302621) @@ -361,6 +361,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, @@ -655,7 +656,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: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Jul 12 05:23:14 2016 (r302620) +++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Jul 12 05:31:33 2016 (r302621) @@ -238,61 +238,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); } /**
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607120531.u6C5VXTS064640>