Merge tag 'hyperv-next-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyper...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 Aug 2020 16:26:10 +0000 (09:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 Aug 2020 16:26:10 +0000 (09:26 -0700)
Pull hyperv updates from Wei Liu:

 - A patch series from Andrea to improve vmbus code

 - Two clean-up patches from Alexander and Randy

* tag 'hyperv-next-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
  hyperv: hyperv.h: drop a duplicated word
  tools: hv: change http to https in hv_kvp_daemon.c
  Drivers: hv: vmbus: Remove the lock field from the vmbus_channel struct
  scsi: storvsc: Introduce the per-storvsc_device spinlock
  Drivers: hv: vmbus: Remove unnecessary channel->lock critical sections (sc_list updaters)
  Drivers: hv: vmbus: Use channel_mutex in channel_vp_mapping_show()
  Drivers: hv: vmbus: Remove unnecessary channel->lock critical sections (sc_list readers)
  Drivers: hv: vmbus: Replace cpumask_test_cpu(, cpu_online_mask) with cpu_online()
  Drivers: hv: vmbus: Remove the numa_node field from the vmbus_channel struct
  Drivers: hv: vmbus: Remove the target_vp field from the vmbus_channel struct

drivers/hv/channel.c
drivers/hv/channel_mgmt.c
drivers/hv/hv.c
drivers/hv/vmbus_drv.c
drivers/scsi/storvsc_drv.c
include/linux/hyperv.h
include/uapi/linux/hyperv.h
tools/hv/hv_kvp_daemon.c

index 90070b3..3ebda77 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/uio.h>
 #include <linux/interrupt.h>
 #include <asm/page.h>
+#include <asm/mshyperv.h>
 
 #include "hyperv_vmbus.h"
 
@@ -128,12 +129,8 @@ static int __vmbus_open(struct vmbus_channel *newchannel,
        send_pages = newchannel->ringbuffer_send_offset;
        recv_pages = newchannel->ringbuffer_pagecount - send_pages;
 
-       spin_lock_irqsave(&newchannel->lock, flags);
-       if (newchannel->state != CHANNEL_OPEN_STATE) {
-               spin_unlock_irqrestore(&newchannel->lock, flags);
+       if (newchannel->state != CHANNEL_OPEN_STATE)
                return -EINVAL;
-       }
-       spin_unlock_irqrestore(&newchannel->lock, flags);
 
        newchannel->state = CHANNEL_OPENING_STATE;
        newchannel->onchannel_callback = onchannelcallback;
@@ -176,7 +173,7 @@ static int __vmbus_open(struct vmbus_channel *newchannel,
        open_msg->child_relid = newchannel->offermsg.child_relid;
        open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
        open_msg->downstream_ringbuffer_pageoffset = newchannel->ringbuffer_send_offset;
-       open_msg->target_vp = newchannel->target_vp;
+       open_msg->target_vp = hv_cpu_number_to_vp_number(newchannel->target_cpu);
 
        if (userdatalen)
                memcpy(open_msg->userdata, userdata, userdatalen);
index 417a95e..591106c 100644 (file)
@@ -317,7 +317,6 @@ static struct vmbus_channel *alloc_channel(void)
                return NULL;
 
        spin_lock_init(&channel->sched_lock);
-       spin_lock_init(&channel->lock);
        init_completion(&channel->rescind_event);
 
        INIT_LIST_HEAD(&channel->sc_list);
@@ -400,8 +399,6 @@ static void vmbus_release_relid(u32 relid)
 
 void hv_process_channel_removal(struct vmbus_channel *channel)
 {
-       unsigned long flags;
-
        lockdep_assert_held(&vmbus_connection.channel_mutex);
        BUG_ON(!channel->rescind);
 
@@ -422,14 +419,10 @@ void hv_process_channel_removal(struct vmbus_channel *channel)
        if (channel->offermsg.child_relid != INVALID_RELID)
                vmbus_channel_unmap_relid(channel);
 
-       if (channel->primary_channel == NULL) {
+       if (channel->primary_channel == NULL)
                list_del(&channel->listentry);
-       } else {
-               struct vmbus_channel *primary_channel = channel->primary_channel;
-               spin_lock_irqsave(&primary_channel->lock, flags);
+       else
                list_del(&channel->sc_list);
-               spin_unlock_irqrestore(&primary_channel->lock, flags);
-       }
 
        /*
         * If this is a "perf" channel, updates the hv_numa_map[] masks so that
@@ -470,7 +463,6 @@ static void vmbus_add_channel_work(struct work_struct *work)
        struct vmbus_channel *newchannel =
                container_of(work, struct vmbus_channel, add_channel_work);
        struct vmbus_channel *primary_channel = newchannel->primary_channel;
-       unsigned long flags;
        int ret;
 
        /*
@@ -531,13 +523,10 @@ err_deq_chan:
         */
        newchannel->probe_done = true;
 
-       if (primary_channel == NULL) {
+       if (primary_channel == NULL)
                list_del(&newchannel->listentry);
-       } else {
-               spin_lock_irqsave(&primary_channel->lock, flags);
+       else
                list_del(&newchannel->sc_list);
-               spin_unlock_irqrestore(&primary_channel->lock, flags);
-       }
 
        /* vmbus_process_offer() has mapped the channel. */
        vmbus_channel_unmap_relid(newchannel);
@@ -557,7 +546,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 {
        struct vmbus_channel *channel;
        struct workqueue_struct *wq;
-       unsigned long flags;
        bool fnew = true;
 
        /*
@@ -609,10 +597,10 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
                }
        }
 
-       if (fnew)
+       if (fnew) {
                list_add_tail(&newchannel->listentry,
                              &vmbus_connection.chn_list);
-       else {
+       else {
                /*
                 * Check to see if this is a valid sub-channel.
                 */
@@ -630,9 +618,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
                 * Process the sub-channel.
                 */
                newchannel->primary_channel = channel;
-               spin_lock_irqsave(&channel->lock, flags);
                list_add_tail(&newchannel->sc_list, &channel->sc_list);
-               spin_unlock_irqrestore(&channel->lock, flags);
        }
 
        vmbus_channel_map_relid(newchannel);
@@ -702,10 +688,7 @@ static void init_vp_index(struct vmbus_channel *channel)
                 * In case alloc_cpumask_var() fails, bind it to
                 * VMBUS_CONNECT_CPU.
                 */
-               channel->numa_node = cpu_to_node(VMBUS_CONNECT_CPU);
                channel->target_cpu = VMBUS_CONNECT_CPU;
-               channel->target_vp =
-                       hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU);
                if (perf_chn)
                        hv_set_alloced_cpu(VMBUS_CONNECT_CPU);
                return;
@@ -721,7 +704,6 @@ static void init_vp_index(struct vmbus_channel *channel)
                        continue;
                break;
        }
-       channel->numa_node = numa_node;
        alloced_mask = &hv_context.hv_numa_map[numa_node];
 
        if (cpumask_weight(alloced_mask) ==
@@ -739,7 +721,6 @@ static void init_vp_index(struct vmbus_channel *channel)
        cpumask_set_cpu(target_cpu, alloced_mask);
 
        channel->target_cpu = target_cpu;
-       channel->target_vp = hv_cpu_number_to_vp_number(target_cpu);
 
        free_cpumask_var(available_mask);
 }
index 857290d..da69338 100644 (file)
@@ -241,7 +241,6 @@ int hv_synic_cleanup(unsigned int cpu)
 {
        struct vmbus_channel *channel, *sc;
        bool channel_found = false;
-       unsigned long flags;
 
        /*
         * Hyper-V does not provide a way to change the connect CPU once
@@ -263,14 +262,12 @@ int hv_synic_cleanup(unsigned int cpu)
                        channel_found = true;
                        break;
                }
-               spin_lock_irqsave(&channel->lock, flags);
                list_for_each_entry(sc, &channel->sc_list, sc_list) {
                        if (sc->target_cpu == cpu) {
                                channel_found = true;
                                break;
                        }
                }
-               spin_unlock_irqrestore(&channel->lock, flags);
                if (channel_found)
                        break;
        }
index d69f4ef..b50081c 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/cpu.h>
 #include <linux/sched/task_stack.h>
 
-#include <asm/mshyperv.h>
 #include <linux/delay.h>
 #include <linux/notifier.h>
 #include <linux/ptrace.h>
@@ -227,7 +226,7 @@ static ssize_t numa_node_show(struct device *dev,
        if (!hv_dev->channel)
                return -ENODEV;
 
-       return sprintf(buf, "%d\n", hv_dev->channel->numa_node);
+       return sprintf(buf, "%d\n", cpu_to_node(hv_dev->channel->target_cpu));
 }
 static DEVICE_ATTR_RO(numa_node);
 #endif
@@ -508,18 +507,17 @@ static ssize_t channel_vp_mapping_show(struct device *dev,
 {
        struct hv_device *hv_dev = device_to_hv_device(dev);
        struct vmbus_channel *channel = hv_dev->channel, *cur_sc;
-       unsigned long flags;
        int buf_size = PAGE_SIZE, n_written, tot_written;
        struct list_head *cur;
 
        if (!channel)
                return -ENODEV;
 
+       mutex_lock(&vmbus_connection.channel_mutex);
+
        tot_written = snprintf(buf, buf_size, "%u:%u\n",
                channel->offermsg.child_relid, channel->target_cpu);
 
-       spin_lock_irqsave(&channel->lock, flags);
-
        list_for_each(cur, &channel->sc_list) {
                if (tot_written >= buf_size - 1)
                        break;
@@ -533,7 +531,7 @@ static ssize_t channel_vp_mapping_show(struct device *dev,
                tot_written += n_written;
        }
 
-       spin_unlock_irqrestore(&channel->lock, flags);
+       mutex_unlock(&vmbus_connection.channel_mutex);
 
        return tot_written;
 }
@@ -1717,7 +1715,7 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel,
        /* No CPUs should come up or down during this. */
        cpus_read_lock();
 
-       if (!cpumask_test_cpu(target_cpu, cpu_online_mask)) {
+       if (!cpu_online(target_cpu)) {
                cpus_read_unlock();
                return -EINVAL;
        }
@@ -1779,8 +1777,6 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel,
         */
 
        channel->target_cpu = target_cpu;
-       channel->target_vp = hv_cpu_number_to_vp_number(target_cpu);
-       channel->numa_node = cpu_to_node(target_cpu);
 
        /* See init_vp_index(). */
        if (hv_is_perf_channel(channel))
@@ -2347,7 +2343,6 @@ acpi_walk_err:
 static int vmbus_bus_suspend(struct device *dev)
 {
        struct vmbus_channel *channel, *sc;
-       unsigned long flags;
 
        while (atomic_read(&vmbus_connection.offer_in_progress) != 0) {
                /*
@@ -2405,12 +2400,10 @@ static int vmbus_bus_suspend(struct device *dev)
                        continue;
                }
 
-               spin_lock_irqsave(&channel->lock, flags);
                list_for_each_entry(sc, &channel->sc_list, sc_list) {
                        pr_err("Sub-channel not deleted!\n");
                        WARN_ON_ONCE(1);
                }
-               spin_unlock_irqrestore(&channel->lock, flags);
 
                atomic_inc(&vmbus_connection.nr_chan_fixup_on_resume);
        }
index 2d90cdd..624467e 100644 (file)
@@ -462,6 +462,11 @@ struct storvsc_device {
         * Mask of CPUs bound to subchannels.
         */
        struct cpumask alloced_cpus;
+       /*
+        * Serializes modifications of stor_chns[] from storvsc_do_io()
+        * and storvsc_change_target_cpu().
+        */
+       spinlock_t lock;
        /* Used for vsc/vsp channel reset process */
        struct storvsc_cmd_request init_request;
        struct storvsc_cmd_request reset_request;
@@ -639,7 +644,7 @@ static void storvsc_change_target_cpu(struct vmbus_channel *channel, u32 old,
                return;
 
        /* See storvsc_do_io() -> get_og_chn(). */
-       spin_lock_irqsave(&device->channel->lock, flags);
+       spin_lock_irqsave(&stor_device->lock, flags);
 
        /*
         * Determines if the storvsc device has other channels assigned to
@@ -676,7 +681,7 @@ old_is_alloced:
        WRITE_ONCE(stor_device->stor_chns[new], channel);
        cpumask_set_cpu(new, &stor_device->alloced_cpus);
 
-       spin_unlock_irqrestore(&device->channel->lock, flags);
+       spin_unlock_irqrestore(&stor_device->lock, flags);
 }
 
 static void handle_sc_creation(struct vmbus_channel *new_sc)
@@ -1433,14 +1438,14 @@ static int storvsc_do_io(struct hv_device *device,
                        }
                }
        } else {
-               spin_lock_irqsave(&device->channel->lock, flags);
+               spin_lock_irqsave(&stor_device->lock, flags);
                outgoing_channel = stor_device->stor_chns[q_num];
                if (outgoing_channel != NULL) {
-                       spin_unlock_irqrestore(&device->channel->lock, flags);
+                       spin_unlock_irqrestore(&stor_device->lock, flags);
                        goto found_channel;
                }
                outgoing_channel = get_og_chn(stor_device, q_num);
-               spin_unlock_irqrestore(&device->channel->lock, flags);
+               spin_unlock_irqrestore(&stor_device->lock, flags);
        }
 
 found_channel:
@@ -1881,6 +1886,7 @@ static int storvsc_probe(struct hv_device *device,
        init_waitqueue_head(&stor_device->waiting_to_drain);
        stor_device->device = device;
        stor_device->host = host;
+       spin_lock_init(&stor_device->lock);
        hv_set_drvdata(device, stor_device);
 
        stor_device->port_number = host->host_no;
index 40df310..38100e8 100644 (file)
@@ -803,17 +803,15 @@ struct vmbus_channel {
        u64 sig_event;
 
        /*
-        * Starting with win8, this field will be used to specify
-        * the target virtual processor on which to deliver the interrupt for
-        * the host to guest communication.
-        * Prior to win8, incoming channel interrupts would only
-        * be delivered on cpu 0. Setting this value to 0 would
-        * preserve the earlier behavior.
+        * Starting with win8, this field will be used to specify the
+        * target CPU on which to deliver the interrupt for the host
+        * to guest communication.
+        *
+        * Prior to win8, incoming channel interrupts would only be
+        * delivered on CPU 0. Setting this value to 0 would preserve
+        * the earlier behavior.
         */
-       u32 target_vp;
-       /* The corresponding CPUID in the guest */
        u32 target_cpu;
-       int numa_node;
        /*
         * Support for sub-channels. For high performance devices,
         * it will be useful to have multiple sub-channels to support
@@ -842,12 +840,6 @@ struct vmbus_channel {
         */
        void (*chn_rescind_callback)(struct vmbus_channel *channel);
 
-       /*
-        * The spinlock to protect the structure. It is being used to protect
-        * test-and-set access to various attributes of the structure as well
-        * as all sc_list operations.
-        */
-       spinlock_t lock;
        /*
         * All Sub-channels of a primary channel are linked here.
         */
index 8f24404..6135d92 100644 (file)
@@ -219,7 +219,7 @@ struct hv_do_fcopy {
  * kernel and user-level daemon communicate using a connector channel.
  *
  * The user mode component first registers with the
- * the kernel component. Subsequently, the kernel component requests, data
+ * kernel component. Subsequently, the kernel component requests, data
  * for the specified keys. In response to this message the user mode component
  * fills in the value corresponding to the specified key. We overload the
  * sequence field in the cn_msg header to define our KVP message types.
index ee9c1bb..1e6fd6c 100644 (file)
@@ -437,7 +437,7 @@ void kvp_get_os_info(void)
 
        /*
         * Parse the /etc/os-release file if present:
-        * http://www.freedesktop.org/software/systemd/man/os-release.html
+        * https://www.freedesktop.org/software/systemd/man/os-release.html
         */
        file = fopen("/etc/os-release", "r");
        if (file != NULL) {