All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: kys@microsoft.com, gregkh@linuxfoundation.org
Cc: devel@linuxdriverproject.org,
	Stephen Hemminger <sthemmin@microsoft.com>,
	virtualization@lists.linux-foundation.org
Subject: [PATCH 01/14] vmbus: use kernel bitops for traversing interrupt mask
Date: Wed,  1 Feb 2017 08:28:48 -0800	[thread overview]
Message-ID: <20170201162901.3894-2-sthemmin@microsoft.com> (raw)
In-Reply-To: <20170201162901.3894-1-sthemmin@microsoft.com>

Use standard kernel operations for find first set bit to traverse
the channel bit array. This has added benefit of speeding up
lookup on 64 bit and because it uses find first set instruction.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 drivers/hv/channel.c      |  8 ++-----
 drivers/hv/connection.c   | 55 +++++++++++++++--------------------------------
 drivers/hv/hyperv_vmbus.h | 16 ++++++++------
 drivers/hv/vmbus_drv.c    |  4 +---
 4 files changed, 29 insertions(+), 54 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index be34547cdb68..a016c5c0e472 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -47,12 +47,8 @@ void vmbus_setevent(struct vmbus_channel *channel)
 	 * For channels marked as in "low latency" mode
 	 * bypass the monitor page mechanism.
 	 */
-	if ((channel->offermsg.monitor_allocated) &&
-	    (!channel->low_latency)) {
-		/* Each u32 represents 32 channels */
-		sync_set_bit(channel->offermsg.child_relid & 31,
-			(unsigned long *) vmbus_connection.send_int_page +
-			(channel->offermsg.child_relid >> 5));
+	if (channel->offermsg.monitor_allocated && !channel->low_latency) {
+		vmbus_send_interrupt(channel->offermsg.child_relid);
 
 		/* Get the child to parent monitor page */
 		monitorpage = vmbus_connection.monitor_pages[1];
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 307a5a8937f6..1766ef03e78d 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -379,17 +379,11 @@ static void process_chn_event(u32 relid)
  */
 void vmbus_on_event(unsigned long data)
 {
-	u32 dword;
-	u32 maxdword;
-	int bit;
-	u32 relid;
-	u32 *recv_int_page = NULL;
-	void *page_addr;
-	int cpu = smp_processor_id();
-	union hv_synic_event_flags *event;
+	unsigned long *recv_int_page;
+	u32 maxbits, relid;
 
 	if (vmbus_proto_version < VERSION_WIN8) {
-		maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5;
+		maxbits = MAX_NUM_CHANNELS_SUPPORTED;
 		recv_int_page = vmbus_connection.recv_int_page;
 	} else {
 		/*
@@ -397,35 +391,24 @@ void vmbus_on_event(unsigned long data)
 		 * can be directly checked to get the id of the channel
 		 * that has the interrupt pending.
 		 */
-		maxdword = HV_EVENT_FLAGS_DWORD_COUNT;
-		page_addr = hv_context.synic_event_page[cpu];
-		event = (union hv_synic_event_flags *)page_addr +
+		int cpu = smp_processor_id();
+		void *page_addr = hv_context.synic_event_page[cpu];
+		union hv_synic_event_flags *event
+			= (union hv_synic_event_flags *)page_addr +
 						 VMBUS_MESSAGE_SINT;
-		recv_int_page = event->flags32;
-	}
-
 
+		maxbits = HV_EVENT_FLAGS_COUNT;
+		recv_int_page = event->flags;
+	}
 
-	/* Check events */
-	if (!recv_int_page)
+	if (unlikely(!recv_int_page))
 		return;
-	for (dword = 0; dword < maxdword; dword++) {
-		if (!recv_int_page[dword])
-			continue;
-		for (bit = 0; bit < 32; bit++) {
-			if (sync_test_and_clear_bit(bit,
-				(unsigned long *)&recv_int_page[dword])) {
-				relid = (dword << 5) + bit;
-
-				if (relid == 0)
-					/*
-					 * Special case - vmbus
-					 * channel protocol msg
-					 */
-					continue;
 
+	for_each_set_bit(relid, recv_int_page, maxbits) {
+		if (sync_test_and_clear_bit(relid, recv_int_page)) {
+			/* Special case - vmbus channel protocol msg */
+			if (relid != 0)
 				process_chn_event(relid);
-			}
 		}
 	}
 }
@@ -491,12 +474,8 @@ void vmbus_set_event(struct vmbus_channel *channel)
 {
 	u32 child_relid = channel->offermsg.child_relid;
 
-	if (!channel->is_dedicated_interrupt) {
-		/* Each u32 represents 32 channels */
-		sync_set_bit(child_relid & 31,
-			(unsigned long *)vmbus_connection.send_int_page +
-			(child_relid >> 5));
-	}
+	if (!channel->is_dedicated_interrupt)
+		vmbus_send_interrupt(child_relid);
 
 	hv_do_hypercall(HVCALL_SIGNAL_EVENT, channel->sig_event, NULL);
 }
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 86b56b677dc3..2749a4142889 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -40,11 +40,9 @@
  */
 #define HV_UTIL_NEGO_TIMEOUT 55
 
-
-
-
-#define HV_EVENT_FLAGS_BYTE_COUNT	(256)
-#define HV_EVENT_FLAGS_DWORD_COUNT	(256 / sizeof(u32))
+/* Define synthetic interrupt controller flag constants. */
+#define HV_EVENT_FLAGS_COUNT		(256 * 8)
+#define HV_EVENT_FLAGS_LONG_COUNT	(256 / sizeof(unsigned long))
 
 /*
  * Timer configuration register.
@@ -65,8 +63,7 @@ union hv_timer_config {
 
 /* Define the synthetic interrupt controller event flags format. */
 union hv_synic_event_flags {
-	u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT];
-	u32 flags32[HV_EVENT_FLAGS_DWORD_COUNT];
+	unsigned long flags[HV_EVENT_FLAGS_LONG_COUNT];
 };
 
 /* Define SynIC control register. */
@@ -358,6 +355,11 @@ struct vmbus_msginfo {
 
 extern struct vmbus_connection vmbus_connection;
 
+static inline void vmbus_send_interrupt(u32 relid)
+{
+	sync_set_bit(relid, vmbus_connection.send_int_page);
+}
+
 enum vmbus_message_handler_type {
 	/* The related handler can sleep. */
 	VMHT_BLOCKING = 0,
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f8ebe13cf251..c1b27026f744 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -908,10 +908,8 @@ static void vmbus_isr(void)
 		(vmbus_proto_version == VERSION_WIN7)) {
 
 		/* Since we are a child, we only need to check bit 0 */
-		if (sync_test_and_clear_bit(0,
-			(unsigned long *) &event->flags32[0])) {
+		if (sync_test_and_clear_bit(0, event->flags))
 			handled = true;
-		}
 	} else {
 		/*
 		 * Our host is win8 or above. The signaling mechanism
-- 
2.11.0

  reply	other threads:[~2017-02-01 16:28 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-01 16:28 [PATCH 00/14] hyperv: vmbus related patches Stephen Hemminger
2017-02-01 16:28 ` Stephen Hemminger [this message]
2017-02-01 16:28 ` [PATCH 02/14] vmbus: drop no longer used kick_q argument Stephen Hemminger
2017-02-01 16:28 ` [PATCH 03/14] vmbus: remove no longer used signal_policy Stephen Hemminger
2017-02-01 16:28 ` [PATCH 04/14] vmbus: remove unused kickq argument to sendpacket Stephen Hemminger
2017-02-01 16:28 ` [PATCH 05/14] netvsc: remove no longer needed receive staging buffers Stephen Hemminger
2017-02-05 23:40   ` KY Srinivasan via Virtualization
2017-02-07  0:32     ` Stephen Hemminger via Virtualization
     [not found]     ` <BLUPR0301MB209810C0172361C40F9ABDCBCC430@BLUPR0301MB2098.namprd03.prod.outlook.com>
2017-02-10 14:55       ` gregkh
2017-02-01 16:28 ` [PATCH 06/14] vmbus: remove per channel state Stephen Hemminger
2017-02-01 16:28 ` [PATCH 07/14] vmbus: callback is in softirq not workqueue Stephen Hemminger
2017-02-01 16:28 ` [PATCH 08/14] vmbus: put related per-cpu variable together Stephen Hemminger
2017-02-01 16:28 ` [PATCH 09/14] vmbus: change to per channel tasklet Stephen Hemminger
2017-02-01 16:28 ` [PATCH 10/14] vmbus: add direct isr callback mode Stephen Hemminger
2017-02-01 16:28 ` [PATCH 11/14] vmbus: remove conditional locking of vmbus_write Stephen Hemminger
2017-02-01 16:28 ` [PATCH 12/14] vmbus: expose hv_begin/end_read Stephen Hemminger
2017-02-01 16:29 ` [PATCH 13/14] vmbus: constify parameters where possible Stephen Hemminger
2017-02-01 16:29 ` [PATCH 14/14] vmbus: replace modulus operation with subtraction Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170201162901.3894-2-sthemmin@microsoft.com \
    --to=stephen@networkplumber.org \
    --cc=devel@linuxdriverproject.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=kys@microsoft.com \
    --cc=sthemmin@microsoft.com \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.