Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Jul 2016 03:14:29 +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: r302692 - in head/sys: conf dev/hyperv/vmbus modules/hyperv/vmbus
Message-ID:  <201607130314.u6D3ETT6048557@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Wed Jul 13 03:14:29 2016
New Revision: 302692
URL: https://svnweb.freebsd.org/changeset/base/302692

Log:
  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

Deleted:
  head/sys/dev/hyperv/vmbus/hv_connection.c
Modified:
  head/sys/conf/files.amd64
  head/sys/conf/files.i386
  head/sys/dev/hyperv/vmbus/hv_channel.c
  head/sys/dev/hyperv/vmbus/vmbus_var.h
  head/sys/modules/hyperv/vmbus/Makefile

Modified: head/sys/conf/files.amd64
==============================================================================
--- head/sys/conf/files.amd64	Wed Jul 13 02:07:36 2016	(r302691)
+++ head/sys/conf/files.amd64	Wed Jul 13 03:14:29 2016	(r302692)
@@ -272,7 +272,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: head/sys/conf/files.i386
==============================================================================
--- head/sys/conf/files.i386	Wed Jul 13 02:07:36 2016	(r302691)
+++ head/sys/conf/files.i386	Wed Jul 13 03:14:29 2016	(r302692)
@@ -248,7 +248,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: head/sys/dev/hyperv/vmbus/hv_channel.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel.c	Wed Jul 13 02:07:36 2016	(r302691)
+++ head/sys/dev/hyperv/vmbus/hv_channel.c	Wed Jul 13 03:14:29 2016	(r302692)
@@ -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: head/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_var.h	Wed Jul 13 02:07:36 2016	(r302691)
+++ head/sys/dev/hyperv/vmbus/vmbus_var.h	Wed Jul 13 03:14:29 2016	(r302692)
@@ -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 *);

Modified: head/sys/modules/hyperv/vmbus/Makefile
==============================================================================
--- head/sys/modules/hyperv/vmbus/Makefile	Wed Jul 13 02:07:36 2016	(r302691)
+++ head/sys/modules/hyperv/vmbus/Makefile	Wed Jul 13 03:14:29 2016	(r302692)
@@ -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?201607130314.u6D3ETT6048557>