Date: Tue, 11 Oct 2016 07:00:43 +0000 (UTC) From: Sepherosa Ziehau <sephe@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307020 - in stable/10/sys: conf dev/hyperv/vmbus modules/hyperv/vmbus Message-ID: <201610110700.u9B70hZl096520@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sephe Date: Tue Oct 11 07:00:43 2016 New Revision: 307020 URL: https://svnweb.freebsd.org/changeset/base/307020 Log: MFC 302636-302638,302692 302636 hyperv/vmbus: Move channel map to vmbus_softc Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6982 302637 hyperv/vmbus: Remove needed bits Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7002 302638 hyperv/vmbus: Destroy channel list lock upon attach failure and detach. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7003 302692 hyperv/vmbus: Merge hv_connection.c into hv_channel.c Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7004 Deleted: stable/10/sys/dev/hyperv/vmbus/hv_connection.c Modified: stable/10/sys/conf/files.amd64 stable/10/sys/conf/files.i386 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_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_var.h 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:46:24 2016 (r307019) +++ stable/10/sys/conf/files.amd64 Tue Oct 11 07:00:43 2016 (r307020) @@ -273,7 +273,6 @@ dev/hyperv/utilities/hv_timesync.c opt 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 Modified: stable/10/sys/conf/files.i386 ============================================================================== --- stable/10/sys/conf/files.i386 Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/conf/files.i386 Tue Oct 11 07:00:43 2016 (r307020) @@ -250,7 +250,6 @@ dev/hyperv/utilities/hv_timesync.c opt 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 Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:00:43 2016 (r307020) @@ -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, } 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; + } + } +} 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:46:24 2016 (r307019) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 07:00:43 2016 (r307020) @@ -126,7 +126,7 @@ vmbus_channel_process_offer(hv_vmbus_cha */ printf("VMBUS: got channel0 offer\n"); } else { - hv_vmbus_g_connection.channels[relid] = new_channel; + sc->vmbus_chmap[relid] = new_channel; } TAILQ_FOREACH(channel, &sc->vmbus_chlist, ch_link) { @@ -354,10 +354,10 @@ vmbus_channel_on_offer_rescind(struct vm rescind->child_rel_id); } - channel = hv_vmbus_g_connection.channels[rescind->child_rel_id]; + channel = sc->vmbus_chmap[rescind->child_rel_id]; if (channel == NULL) return; - hv_vmbus_g_connection.channels[rescind->child_rel_id] = NULL; + sc->vmbus_chmap[rescind->child_rel_id] = NULL; taskqueue_enqueue(taskqueue_thread, &channel->ch_detach_task); } @@ -454,8 +454,8 @@ hv_vmbus_release_unattached_channels(str } hv_vmbus_free_vmbus_channel(channel); } - bzero(hv_vmbus_g_connection.channels, - sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX); + bzero(sc->vmbus_chmap, + sizeof(struct hv_vmbus_channel *) * VMBUS_CHAN_MAX); mtx_unlock(&sc->vmbus_chlist_lock); } 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:46:24 2016 (r307019) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 07:00:43 2016 (r307020) @@ -97,25 +97,6 @@ typedef struct hv_vmbus_channel_packet_m hv_vmbus_multipage_buffer range; } __packed hv_vmbus_channel_packet_multipage_buffer; -/* - * VM Bus connection states - */ -typedef enum { - HV_DISCONNECTED, - HV_CONNECTING, - HV_CONNECTED, - HV_DISCONNECTING -} hv_vmbus_connect_state; - -typedef struct { - hv_vmbus_connect_state connect_state; - - /** - * channel table for fast lookup through id. - */ - hv_vmbus_channel **channels; -} hv_vmbus_connection; - typedef union { uint32_t as_uint32_t; struct { @@ -177,12 +158,6 @@ typedef struct { uint8_t rsvd_z4[1984]; } hv_vmbus_monitor_page; -/** - * Global variables - */ - -extern hv_vmbus_connection hv_vmbus_g_connection; - /* * Private, VM Bus functions */ @@ -247,10 +222,4 @@ void hv_vmbus_child_device_register(st int hv_vmbus_child_device_unregister( struct hv_device *child_dev); -/** - * Connection interfaces - */ -int hv_vmbus_connect(struct vmbus_softc *); -int hv_vmbus_disconnect(void); - #endif /* __HYPERV_PRIV_H__ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 07:00:43 2016 (r307020) @@ -1212,6 +1212,9 @@ vmbus_doattach(struct vmbus_softc *sc) sc->vmbus_gpadl = VMBUS_GPADL_START; mtx_init(&sc->vmbus_chlist_lock, "vmbus chlist", NULL, MTX_DEF); TAILQ_INIT(&sc->vmbus_chlist); + sc->vmbus_chmap = malloc( + sizeof(struct hv_vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF, + M_WAITOK | M_ZERO); /* * Create context for "post message" Hypercalls @@ -1246,12 +1249,8 @@ vmbus_doattach(struct vmbus_softc *sc) sc->vmbus_flags |= VMBUS_FLAG_SYNIC; /* - * Connect to VMBus in the root partition + * Initialize vmbus, e.g. connect to Hypervisor. */ - ret = hv_vmbus_connect(sc); - if (ret != 0) - goto cleanup; - ret = vmbus_init(sc); if (ret != 0) goto cleanup; @@ -1281,7 +1280,9 @@ cleanup: vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc); sc->vmbus_msg_hc = NULL; } + free(sc->vmbus_chmap, M_DEVBUF); mtx_destroy(&sc->vmbus_scan_lock); + mtx_destroy(&sc->vmbus_chlist_lock); return (ret); } @@ -1342,7 +1343,6 @@ vmbus_detach(device_t dev) hv_vmbus_release_unattached_channels(sc); vmbus_disconnect(sc); - hv_vmbus_disconnect(); if (sc->vmbus_flags & VMBUS_FLAG_SYNIC) { sc->vmbus_flags &= ~VMBUS_FLAG_SYNIC; @@ -1357,7 +1357,10 @@ vmbus_detach(device_t dev) sc->vmbus_msg_hc = NULL; } + free(sc->vmbus_chmap, M_DEVBUF); mtx_destroy(&sc->vmbus_scan_lock); + mtx_destroy(&sc->vmbus_chlist_lock); + return (0); } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 07:00:43 2016 (r307020) @@ -74,6 +74,7 @@ struct vmbus_softc { u_long *vmbus_rx_evtflags; /* compat evtflgs from host */ + struct hv_vmbus_channel **vmbus_chmap; struct vmbus_msghc_ctx *vmbus_msg_hc; struct vmbus_pcpu_data vmbus_pcpu[MAXCPU]; @@ -129,7 +130,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 *); Modified: stable/10/sys/modules/hyperv/vmbus/Makefile ============================================================================== --- stable/10/sys/modules/hyperv/vmbus/Makefile Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/modules/hyperv/vmbus/Makefile Tue Oct 11 07:00:43 2016 (r307020) @@ -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 \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610110700.u9B70hZl096520>