Author: sephe
Date: Wed May 18 02:59:46 2016
New Revision: 300101
URL: https://svnweb.freebsd.org/changeset/base/300101

Log:
  hyperv/vmbus: Use unsigned long for event bits.
  
  And move base channel id calculation out of inner loop.  This prepares
  for more event processing optimization.
  
  MFC after:    1 week
  Sponsored by: Microsoft OSTC
  Differential Revision:        https://reviews.freebsd.org/D6384

Modified:
  head/sys/dev/hyperv/vmbus/hv_connection.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h

Modified: head/sys/dev/hyperv/vmbus/hv_connection.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_connection.c   Wed May 18 02:10:05 2016        
(r300100)
+++ head/sys/dev/hyperv/vmbus/hv_connection.c   Wed May 18 02:59:46 2016        
(r300101)
@@ -294,13 +294,10 @@ hv_vmbus_disconnect(void) {
 void
 hv_vmbus_on_events(int cpu)
 {
-       int bit;
-       int dword;
-       void *page_addr;
-       uint32_t* recv_interrupt_page = NULL;
-       int rel_id;
-       int maxdword;
+       unsigned long *intr_page;
        hv_vmbus_synic_event_flags *event;
+       void *page_addr;
+       int page_cnt, pg;
 
        KASSERT(cpu <= mp_maxid, ("VMBUS: hv_vmbus_on_events: "
            "cpu out of range!"));
@@ -310,39 +307,42 @@ hv_vmbus_on_events(int cpu)
            page_addr + HV_VMBUS_MESSAGE_SINT;
        if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) ||
            (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) {
-               maxdword = HV_MAX_NUM_CHANNELS_SUPPORTED >> 5;
+               page_cnt = HV_MAX_NUM_CHANNELS_SUPPORTED >>
+                   HV_CHANNEL_ULONG_SHIFT;
                /*
                 * receive size is 1/2 page and divide that by 4 bytes
                 */
-               if (atomic_testandclear_int(&event->flags32[0], 0)) {
-                       recv_interrupt_page =
-                           hv_vmbus_g_connection.recv_interrupt_page;
-               } else {
+               if (atomic_testandclear_int(&event->flags32[0], 0))
+                       intr_page = hv_vmbus_g_connection.recv_interrupt_page;
+               else
                        return;
-               }
        } else {
                /*
                 * 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.
                 */
-               maxdword = HV_EVENT_FLAGS_DWORD_COUNT;
-               recv_interrupt_page = event->flags32;
+               page_cnt = HV_EVENT_FLAGS_ULONG_COUNT;
+               intr_page = event->flagsul;
        }
 
        /*
         * Check events
         */
-       for (dword = 0; dword < maxdword; dword++) {
-               if (recv_interrupt_page[dword] == 0)
+       for (pg = 0; pg < page_cnt; pg++) {
+               uint32_t rel_id_base;
+               int bit;
+
+               if (intr_page[pg] == 0)
                        continue;
 
-               for (bit = 0; bit < HV_CHANNEL_DWORD_LEN; bit++) {
-                       if (atomic_testandclear_int(
-                           &recv_interrupt_page[dword], bit)) {
+               rel_id_base = pg << HV_CHANNEL_ULONG_SHIFT;
+               for (bit = 0; bit < HV_CHANNEL_ULONG_LEN; bit++) {
+                       if (atomic_testandclear_long(&intr_page[pg], bit)) {
                                struct hv_vmbus_channel *channel;
+                               uint32_t rel_id;
 
-                               rel_id = (dword << 5) + bit;
+                               rel_id = rel_id_base + bit;
                                channel =
                                    hv_vmbus_g_connection.channels[rel_id];
 
@@ -357,7 +357,7 @@ hv_vmbus_on_events(int cpu)
                                taskqueue_enqueue(channel->rxq,
                                    &channel->channel_task);
                        }
-               }
+               }
        }
 }
 

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h   Wed May 18 02:10:05 2016        
(r300100)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h   Wed May 18 02:59:46 2016        
(r300101)
@@ -57,10 +57,18 @@ typedef uint16_t hv_vmbus_status;
 #define HV_EVENT_FLAGS_COUNT        (256 * 8)
 #define HV_EVENT_FLAGS_BYTE_COUNT   (256)
 #define HV_EVENT_FLAGS_DWORD_COUNT  (256 / sizeof(uint32_t))
+#define HV_EVENT_FLAGS_ULONG_COUNT  (256 / sizeof(unsigned long))
 
 /**
  * max channel count <== event_flags_dword_count * bit_of_dword
  */
+#ifdef __LP64__
+#define HV_CHANNEL_ULONG_LEN       (64)
+#define HV_CHANNEL_ULONG_SHIFT     (6)
+#else
+#define HV_CHANNEL_ULONG_LEN       (32)
+#define HV_CHANNEL_ULONG_SHIFT     (5)
+#endif
 #define HV_CHANNEL_DWORD_LEN        (32)
 #define HV_CHANNEL_MAX_COUNT        \
        ((HV_EVENT_FLAGS_DWORD_COUNT) * HV_CHANNEL_DWORD_LEN)
@@ -575,7 +583,9 @@ typedef struct {
 typedef union {
        uint8_t         flags8[HV_EVENT_FLAGS_BYTE_COUNT];
        uint32_t        flags32[HV_EVENT_FLAGS_DWORD_COUNT];
+       unsigned long   flagsul[HV_EVENT_FLAGS_ULONG_COUNT];
 } hv_vmbus_synic_event_flags;
+CTASSERT(sizeof(hv_vmbus_synic_event_flags) == HV_EVENT_FLAGS_BYTE_COUNT);
 
 #define HV_X64_CPUID_MIN       (0x40000005)
 #define HV_X64_CPUID_MAX       (0x4000ffff)
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to