From e71d17193d520345f9280ecf7654ac59e894b557 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Wed, 13 Jul 2016 03:14:29 +0000 Subject: [PATCH] hyperv/vmbus: Merge hv_connection.c into hv_channel.c MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7004 --- sys/conf/files.amd64 | 1 - sys/conf/files.i386 | 1 - sys/dev/hyperv/vmbus/hv_channel.c | 96 ++++++++++++++++++- sys/dev/hyperv/vmbus/hv_connection.c | 136 --------------------------- sys/dev/hyperv/vmbus/vmbus_var.h | 1 - sys/modules/hyperv/vmbus/Makefile | 1 - 6 files changed, 95 insertions(+), 141 deletions(-) delete mode 100644 sys/dev/hyperv/vmbus/hv_connection.c diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 06fec361b00..9a6bdcb18ed 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -272,7 +272,6 @@ dev/hyperv/utilities/hv_timesync.c optional hyperv dev/hyperv/utilities/hv_util.c optional hyperv dev/hyperv/vmbus/hv_channel.c optional hyperv dev/hyperv/vmbus/hv_channel_mgmt.c optional hyperv -dev/hyperv/vmbus/hv_connection.c optional hyperv dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 04e81d78947..6d7253fd5b7 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -248,7 +248,6 @@ dev/hyperv/utilities/hv_timesync.c optional hyperv dev/hyperv/utilities/hv_util.c optional hyperv dev/hyperv/vmbus/hv_channel.c optional hyperv dev/hyperv/vmbus/hv_channel_mgmt.c optional hyperv -dev/hyperv/vmbus/hv_connection.c optional hyperv dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv diff --git a/sys/dev/hyperv/vmbus/hv_channel.c b/sys/dev/hyperv/vmbus/hv_channel.c index 6bb46edbff2..1c84c4f7f02 100644 --- a/sys/dev/hyperv/vmbus/hv_channel.c +++ b/sys/dev/hyperv/vmbus/hv_channel.c @@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$"); static void vmbus_channel_set_event(hv_vmbus_channel* channel); static void VmbusProcessChannelEvent(void* channel, int pending); +static void vmbus_chan_update_evtflagcnt(struct vmbus_softc *, + const struct hv_vmbus_channel *); /** * @brief Trigger an event notification on the specified channel @@ -207,7 +209,7 @@ hv_vmbus_channel_open( new_channel->on_channel_callback = pfn_on_channel_callback; new_channel->channel_callback_context = context; - vmbus_on_channel_open(new_channel); + vmbus_chan_update_evtflagcnt(sc, new_channel); new_channel->rxq = VMBUS_PCPU_GET(new_channel->vmbus_sc, event_tq, new_channel->target_cpu); @@ -883,3 +885,95 @@ VmbusProcessChannelEvent(void* context, int pending) } while (is_batched_reading && (bytes_to_read != 0)); } } + +static __inline void +vmbus_event_flags_proc(struct vmbus_softc *sc, volatile u_long *event_flags, + int flag_cnt) +{ + int f; + + for (f = 0; f < flag_cnt; ++f) { + uint32_t rel_id_base; + u_long flags; + int bit; + + if (event_flags[f] == 0) + continue; + + flags = atomic_swap_long(&event_flags[f], 0); + rel_id_base = f << VMBUS_EVTFLAG_SHIFT; + + while ((bit = ffsl(flags)) != 0) { + struct hv_vmbus_channel *channel; + uint32_t rel_id; + + --bit; /* NOTE: ffsl is 1-based */ + flags &= ~(1UL << bit); + + rel_id = rel_id_base + bit; + channel = sc->vmbus_chmap[rel_id]; + + /* if channel is closed or closing */ + if (channel == NULL || channel->rxq == NULL) + continue; + + if (channel->batched_reading) + hv_ring_buffer_read_begin(&channel->inbound); + taskqueue_enqueue(channel->rxq, &channel->channel_task); + } + } +} + +void +vmbus_event_proc(struct vmbus_softc *sc, int cpu) +{ + struct vmbus_evtflags *eventf; + + /* + * On Host with Win8 or above, the event page can be checked directly + * to get the id of the channel that has the pending interrupt. + */ + eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE; + vmbus_event_flags_proc(sc, eventf->evt_flags, + VMBUS_PCPU_GET(sc, event_flags_cnt, cpu)); +} + +void +vmbus_event_proc_compat(struct vmbus_softc *sc, int cpu) +{ + struct vmbus_evtflags *eventf; + + eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE; + if (atomic_testandclear_long(&eventf->evt_flags[0], 0)) { + vmbus_event_flags_proc(sc, sc->vmbus_rx_evtflags, + VMBUS_CHAN_MAX_COMPAT >> VMBUS_EVTFLAG_SHIFT); + } +} + +static void +vmbus_chan_update_evtflagcnt(struct vmbus_softc *sc, + const struct hv_vmbus_channel *chan) +{ + volatile int *flag_cnt_ptr; + int flag_cnt; + + flag_cnt = (chan->offer_msg.child_rel_id / VMBUS_EVTFLAG_LEN) + 1; + flag_cnt_ptr = VMBUS_PCPU_PTR(sc, event_flags_cnt, chan->target_cpu); + + for (;;) { + int old_flag_cnt; + + old_flag_cnt = *flag_cnt_ptr; + if (old_flag_cnt >= flag_cnt) + break; + if (atomic_cmpset_int(flag_cnt_ptr, old_flag_cnt, flag_cnt)) { + if (bootverbose) { + device_printf(sc->vmbus_dev, + "channel%u update cpu%d flag_cnt to %d\n", + chan->offer_msg.child_rel_id, + chan->target_cpu, flag_cnt); + } + break; + } + } +} diff --git a/sys/dev/hyperv/vmbus/hv_connection.c b/sys/dev/hyperv/vmbus/hv_connection.c deleted file mode 100644 index 4bd50299b4d..00000000000 --- a/sys/dev/hyperv/vmbus/hv_connection.c +++ /dev/null @@ -1,136 +0,0 @@ -/*- - * Copyright (c) 2009-2012,2016 Microsoft Corp. - * Copyright (c) 2012 NetApp Inc. - * Copyright (c) 2012 Citrix Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static __inline void -vmbus_event_flags_proc(struct vmbus_softc *sc, volatile u_long *event_flags, - int flag_cnt) -{ - int f; - - for (f = 0; f < flag_cnt; ++f) { - uint32_t rel_id_base; - u_long flags; - int bit; - - if (event_flags[f] == 0) - continue; - - flags = atomic_swap_long(&event_flags[f], 0); - rel_id_base = f << VMBUS_EVTFLAG_SHIFT; - - while ((bit = ffsl(flags)) != 0) { - struct hv_vmbus_channel *channel; - uint32_t rel_id; - - --bit; /* NOTE: ffsl is 1-based */ - flags &= ~(1UL << bit); - - rel_id = rel_id_base + bit; - channel = sc->vmbus_chmap[rel_id]; - - /* if channel is closed or closing */ - if (channel == NULL || channel->rxq == NULL) - continue; - - if (channel->batched_reading) - hv_ring_buffer_read_begin(&channel->inbound); - taskqueue_enqueue(channel->rxq, &channel->channel_task); - } - } -} - -void -vmbus_event_proc(struct vmbus_softc *sc, int cpu) -{ - struct vmbus_evtflags *eventf; - - /* - * On Host with Win8 or above, the event page can be checked directly - * to get the id of the channel that has the pending interrupt. - */ - eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE; - vmbus_event_flags_proc(sc, eventf->evt_flags, - VMBUS_PCPU_GET(sc, event_flags_cnt, cpu)); -} - -void -vmbus_event_proc_compat(struct vmbus_softc *sc, int cpu) -{ - struct vmbus_evtflags *eventf; - - eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE; - if (atomic_testandclear_long(&eventf->evt_flags[0], 0)) { - vmbus_event_flags_proc(sc, sc->vmbus_rx_evtflags, - VMBUS_CHAN_MAX_COMPAT >> VMBUS_EVTFLAG_SHIFT); - } -} - -void -vmbus_on_channel_open(const struct hv_vmbus_channel *chan) -{ - volatile int *flag_cnt_ptr; - int flag_cnt; - - flag_cnt = (chan->offer_msg.child_rel_id / VMBUS_EVTFLAG_LEN) + 1; - flag_cnt_ptr = VMBUS_PCPU_PTR(chan->vmbus_sc, event_flags_cnt, - chan->target_cpu); - - for (;;) { - int old_flag_cnt; - - old_flag_cnt = *flag_cnt_ptr; - if (old_flag_cnt >= flag_cnt) - break; - if (atomic_cmpset_int(flag_cnt_ptr, old_flag_cnt, flag_cnt)) { - if (bootverbose) { - printf("VMBUS: channel%u update " - "cpu%d flag_cnt to %d\n", - chan->offer_msg.child_rel_id, - chan->target_cpu, flag_cnt); - } - break; - } - } -} diff --git a/sys/dev/hyperv/vmbus/vmbus_var.h b/sys/dev/hyperv/vmbus/vmbus_var.h index c04f28c5e61..2c504c78f65 100644 --- a/sys/dev/hyperv/vmbus/vmbus_var.h +++ b/sys/dev/hyperv/vmbus/vmbus_var.h @@ -131,7 +131,6 @@ struct trapframe; struct vmbus_message; struct vmbus_msghc; -void vmbus_on_channel_open(const struct hv_vmbus_channel *); void vmbus_event_proc(struct vmbus_softc *, int); void vmbus_event_proc_compat(struct vmbus_softc *, int); void vmbus_handle_intr(struct trapframe *); diff --git a/sys/modules/hyperv/vmbus/Makefile b/sys/modules/hyperv/vmbus/Makefile index 89b0e743bac..c817ceca597 100644 --- a/sys/modules/hyperv/vmbus/Makefile +++ b/sys/modules/hyperv/vmbus/Makefile @@ -6,7 +6,6 @@ KMOD= hv_vmbus SRCS= hv_channel.c \ hv_channel_mgmt.c \ - hv_connection.c \ hv_ring_buffer.c \ hyperv.c \ hyperv_busdma.c \