hv: make "monitor_pages" a "real" pointer array
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 13 Sep 2013 18:32:55 +0000 (11:32 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 26 Sep 2013 16:01:16 +0000 (09:01 -0700)
monitor_pages was a void pointer, containing an unknown number of arrays that
we just "knew" were a child and parent array of a specific size.  Instead of
that implicit knowledge, let's make them a real pointer, allowing us to have
type safety, and a semblance of sane addressing schemes.

Tested-by: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hv/channel.c
drivers/hv/connection.c
drivers/hv/hyperv_vmbus.h

index dde30b48c56c5ea93caf04b3ab6c40684341b028..04bf06560085ea8c1294e59de0dc11c71d37c6fc 100644 (file)
@@ -47,8 +47,8 @@ static void vmbus_setevent(struct vmbus_channel *channel)
                        (unsigned long *) vmbus_connection.send_int_page +
                        (channel->offermsg.child_relid >> 5));
 
-               monitorpage = vmbus_connection.monitor_pages;
-               monitorpage++; /* Get the child to parent monitor page */
+               /* Get the child to parent monitor page */
+               monitorpage = vmbus_connection.monitor_pages[1];
 
                sync_set_bit(channel->monitor_bit,
                        (unsigned long *)&monitorpage->trigger_group
@@ -69,8 +69,7 @@ void vmbus_get_debug_info(struct vmbus_channel *channel,
        u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
        u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
 
-       monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
-
+       monitorpage = vmbus_connection.monitor_pages[0];
        debuginfo->servermonitor_pending =
                        monitorpage->trigger_group[monitor_group].pending;
        debuginfo->servermonitor_latency =
@@ -79,8 +78,7 @@ void vmbus_get_debug_info(struct vmbus_channel *channel,
                        monitorpage->parameter[monitor_group]
                                        [monitor_offset].connectionid.u.id;
 
-       monitorpage++;
-
+       monitorpage = vmbus_connection.monitor_pages[1];
        debuginfo->clientmonitor_pending =
                        monitorpage->trigger_group[monitor_group].pending;
        debuginfo->clientmonitor_latency =
index 8f4743ab5fb279ae416fbce5ff4e16e58db45eaf..4faea979975e3ee9e178688a2e81294976d38706 100644 (file)
@@ -76,10 +76,8 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
        msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT;
        msg->vmbus_version_requested = version;
        msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
-       msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages);
-       msg->monitor_page2 = virt_to_phys(
-                       (void *)((unsigned long)vmbus_connection.monitor_pages +
-                                PAGE_SIZE));
+       msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
+       msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
 
        /*
         * Add to list before we send the request since we may
@@ -169,9 +167,10 @@ int vmbus_connect(void)
         * Setup the monitor notification facility. The 1st page for
         * parent->child and the 2nd page for child->parent
         */
-       vmbus_connection.monitor_pages =
-       (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 1);
-       if (vmbus_connection.monitor_pages == NULL) {
+       vmbus_connection.monitor_pages[0] = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 0);
+       vmbus_connection.monitor_pages[1] = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 0);
+       if ((vmbus_connection.monitor_pages[0] == NULL) ||
+           (vmbus_connection.monitor_pages[1] == NULL)) {
                ret = -ENOMEM;
                goto cleanup;
        }
@@ -229,10 +228,10 @@ cleanup:
                vmbus_connection.int_page = NULL;
        }
 
-       if (vmbus_connection.monitor_pages) {
-               free_pages((unsigned long)vmbus_connection.monitor_pages, 1);
-               vmbus_connection.monitor_pages = NULL;
-       }
+       free_pages((unsigned long)vmbus_connection.monitor_pages[0], 1);
+       free_pages((unsigned long)vmbus_connection.monitor_pages[1], 1);
+       vmbus_connection.monitor_pages[0] = NULL;
+       vmbus_connection.monitor_pages[1] = NULL;
 
        kfree(msginfo);
 
index d84918fe19ab7023e4189b0cb52d98495340abd1..d58c22ffb29a32de1c4063df80da3984a92368c5 100644 (file)
@@ -612,7 +612,7 @@ struct vmbus_connection {
         * 2 pages - 1st page for parent->child notification and 2nd
         * is child->parent notification
         */
-       void *monitor_pages;
+       struct hv_monitor_page *monitor_pages[2];
        struct list_head chn_msg_list;
        spinlock_t channelmsg_lock;