Commit 9ab9bc51 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'hyperv-next-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

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
parents 47ec5303 7deff7b5
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/uio.h> #include <linux/uio.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/mshyperv.h>
#include "hyperv_vmbus.h" #include "hyperv_vmbus.h"
...@@ -128,12 +129,8 @@ static int __vmbus_open(struct vmbus_channel *newchannel, ...@@ -128,12 +129,8 @@ static int __vmbus_open(struct vmbus_channel *newchannel,
send_pages = newchannel->ringbuffer_send_offset; send_pages = newchannel->ringbuffer_send_offset;
recv_pages = newchannel->ringbuffer_pagecount - send_pages; recv_pages = newchannel->ringbuffer_pagecount - send_pages;
spin_lock_irqsave(&newchannel->lock, flags); if (newchannel->state != CHANNEL_OPEN_STATE)
if (newchannel->state != CHANNEL_OPEN_STATE) {
spin_unlock_irqrestore(&newchannel->lock, flags);
return -EINVAL; return -EINVAL;
}
spin_unlock_irqrestore(&newchannel->lock, flags);
newchannel->state = CHANNEL_OPENING_STATE; newchannel->state = CHANNEL_OPENING_STATE;
newchannel->onchannel_callback = onchannelcallback; newchannel->onchannel_callback = onchannelcallback;
...@@ -176,7 +173,7 @@ static int __vmbus_open(struct vmbus_channel *newchannel, ...@@ -176,7 +173,7 @@ static int __vmbus_open(struct vmbus_channel *newchannel,
open_msg->child_relid = newchannel->offermsg.child_relid; open_msg->child_relid = newchannel->offermsg.child_relid;
open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
open_msg->downstream_ringbuffer_pageoffset = newchannel->ringbuffer_send_offset; 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) if (userdatalen)
memcpy(open_msg->userdata, userdata, userdatalen); memcpy(open_msg->userdata, userdata, userdatalen);
......
...@@ -317,7 +317,6 @@ static struct vmbus_channel *alloc_channel(void) ...@@ -317,7 +317,6 @@ static struct vmbus_channel *alloc_channel(void)
return NULL; return NULL;
spin_lock_init(&channel->sched_lock); spin_lock_init(&channel->sched_lock);
spin_lock_init(&channel->lock);
init_completion(&channel->rescind_event); init_completion(&channel->rescind_event);
INIT_LIST_HEAD(&channel->sc_list); INIT_LIST_HEAD(&channel->sc_list);
...@@ -400,8 +399,6 @@ static void vmbus_release_relid(u32 relid) ...@@ -400,8 +399,6 @@ static void vmbus_release_relid(u32 relid)
void hv_process_channel_removal(struct vmbus_channel *channel) void hv_process_channel_removal(struct vmbus_channel *channel)
{ {
unsigned long flags;
lockdep_assert_held(&vmbus_connection.channel_mutex); lockdep_assert_held(&vmbus_connection.channel_mutex);
BUG_ON(!channel->rescind); BUG_ON(!channel->rescind);
...@@ -422,14 +419,10 @@ void hv_process_channel_removal(struct vmbus_channel *channel) ...@@ -422,14 +419,10 @@ void hv_process_channel_removal(struct vmbus_channel *channel)
if (channel->offermsg.child_relid != INVALID_RELID) if (channel->offermsg.child_relid != INVALID_RELID)
vmbus_channel_unmap_relid(channel); vmbus_channel_unmap_relid(channel);
if (channel->primary_channel == NULL) { if (channel->primary_channel == NULL)
list_del(&channel->listentry); list_del(&channel->listentry);
} else { else
struct vmbus_channel *primary_channel = channel->primary_channel;
spin_lock_irqsave(&primary_channel->lock, flags);
list_del(&channel->sc_list); 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 * 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) ...@@ -470,7 +463,6 @@ static void vmbus_add_channel_work(struct work_struct *work)
struct vmbus_channel *newchannel = struct vmbus_channel *newchannel =
container_of(work, struct vmbus_channel, add_channel_work); container_of(work, struct vmbus_channel, add_channel_work);
struct vmbus_channel *primary_channel = newchannel->primary_channel; struct vmbus_channel *primary_channel = newchannel->primary_channel;
unsigned long flags;
int ret; int ret;
/* /*
...@@ -531,13 +523,10 @@ static void vmbus_add_channel_work(struct work_struct *work) ...@@ -531,13 +523,10 @@ static void vmbus_add_channel_work(struct work_struct *work)
*/ */
newchannel->probe_done = true; newchannel->probe_done = true;
if (primary_channel == NULL) { if (primary_channel == NULL)
list_del(&newchannel->listentry); list_del(&newchannel->listentry);
} else { else
spin_lock_irqsave(&primary_channel->lock, flags);
list_del(&newchannel->sc_list); list_del(&newchannel->sc_list);
spin_unlock_irqrestore(&primary_channel->lock, flags);
}
/* vmbus_process_offer() has mapped the channel. */ /* vmbus_process_offer() has mapped the channel. */
vmbus_channel_unmap_relid(newchannel); vmbus_channel_unmap_relid(newchannel);
...@@ -557,7 +546,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) ...@@ -557,7 +546,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
{ {
struct vmbus_channel *channel; struct vmbus_channel *channel;
struct workqueue_struct *wq; struct workqueue_struct *wq;
unsigned long flags;
bool fnew = true; bool fnew = true;
/* /*
...@@ -609,10 +597,10 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) ...@@ -609,10 +597,10 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
} }
} }
if (fnew) if (fnew) {
list_add_tail(&newchannel->listentry, list_add_tail(&newchannel->listentry,
&vmbus_connection.chn_list); &vmbus_connection.chn_list);
else { } else {
/* /*
* Check to see if this is a valid sub-channel. * Check to see if this is a valid sub-channel.
*/ */
...@@ -630,9 +618,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) ...@@ -630,9 +618,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
* Process the sub-channel. * Process the sub-channel.
*/ */
newchannel->primary_channel = channel; newchannel->primary_channel = channel;
spin_lock_irqsave(&channel->lock, flags);
list_add_tail(&newchannel->sc_list, &channel->sc_list); list_add_tail(&newchannel->sc_list, &channel->sc_list);
spin_unlock_irqrestore(&channel->lock, flags);
} }
vmbus_channel_map_relid(newchannel); vmbus_channel_map_relid(newchannel);
...@@ -702,10 +688,7 @@ static void init_vp_index(struct vmbus_channel *channel) ...@@ -702,10 +688,7 @@ static void init_vp_index(struct vmbus_channel *channel)
* In case alloc_cpumask_var() fails, bind it to * In case alloc_cpumask_var() fails, bind it to
* VMBUS_CONNECT_CPU. * VMBUS_CONNECT_CPU.
*/ */
channel->numa_node = cpu_to_node(VMBUS_CONNECT_CPU);
channel->target_cpu = VMBUS_CONNECT_CPU; channel->target_cpu = VMBUS_CONNECT_CPU;
channel->target_vp =
hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU);
if (perf_chn) if (perf_chn)
hv_set_alloced_cpu(VMBUS_CONNECT_CPU); hv_set_alloced_cpu(VMBUS_CONNECT_CPU);
return; return;
...@@ -721,7 +704,6 @@ static void init_vp_index(struct vmbus_channel *channel) ...@@ -721,7 +704,6 @@ static void init_vp_index(struct vmbus_channel *channel)
continue; continue;
break; break;
} }
channel->numa_node = numa_node;
alloced_mask = &hv_context.hv_numa_map[numa_node]; alloced_mask = &hv_context.hv_numa_map[numa_node];
if (cpumask_weight(alloced_mask) == if (cpumask_weight(alloced_mask) ==
...@@ -739,7 +721,6 @@ static void init_vp_index(struct vmbus_channel *channel) ...@@ -739,7 +721,6 @@ static void init_vp_index(struct vmbus_channel *channel)
cpumask_set_cpu(target_cpu, alloced_mask); cpumask_set_cpu(target_cpu, alloced_mask);
channel->target_cpu = target_cpu; channel->target_cpu = target_cpu;
channel->target_vp = hv_cpu_number_to_vp_number(target_cpu);
free_cpumask_var(available_mask); free_cpumask_var(available_mask);
} }
......
...@@ -241,7 +241,6 @@ int hv_synic_cleanup(unsigned int cpu) ...@@ -241,7 +241,6 @@ int hv_synic_cleanup(unsigned int cpu)
{ {
struct vmbus_channel *channel, *sc; struct vmbus_channel *channel, *sc;
bool channel_found = false; bool channel_found = false;
unsigned long flags;
/* /*
* Hyper-V does not provide a way to change the connect CPU once * Hyper-V does not provide a way to change the connect CPU once
...@@ -263,14 +262,12 @@ int hv_synic_cleanup(unsigned int cpu) ...@@ -263,14 +262,12 @@ int hv_synic_cleanup(unsigned int cpu)
channel_found = true; channel_found = true;
break; break;
} }
spin_lock_irqsave(&channel->lock, flags);
list_for_each_entry(sc, &channel->sc_list, sc_list) { list_for_each_entry(sc, &channel->sc_list, sc_list) {
if (sc->target_cpu == cpu) { if (sc->target_cpu == cpu) {
channel_found = true; channel_found = true;
break; break;
} }
} }
spin_unlock_irqrestore(&channel->lock, flags);
if (channel_found) if (channel_found)
break; break;
} }
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <asm/mshyperv.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
...@@ -227,7 +226,7 @@ static ssize_t numa_node_show(struct device *dev, ...@@ -227,7 +226,7 @@ static ssize_t numa_node_show(struct device *dev,
if (!hv_dev->channel) if (!hv_dev->channel)
return -ENODEV; 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); static DEVICE_ATTR_RO(numa_node);
#endif #endif
...@@ -508,18 +507,17 @@ static ssize_t channel_vp_mapping_show(struct device *dev, ...@@ -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 hv_device *hv_dev = device_to_hv_device(dev);
struct vmbus_channel *channel = hv_dev->channel, *cur_sc; struct vmbus_channel *channel = hv_dev->channel, *cur_sc;
unsigned long flags;
int buf_size = PAGE_SIZE, n_written, tot_written; int buf_size = PAGE_SIZE, n_written, tot_written;
struct list_head *cur; struct list_head *cur;
if (!channel) if (!channel)
return -ENODEV; return -ENODEV;
mutex_lock(&vmbus_connection.channel_mutex);
tot_written = snprintf(buf, buf_size, "%u:%u\n", tot_written = snprintf(buf, buf_size, "%u:%u\n",
channel->offermsg.child_relid, channel->target_cpu); channel->offermsg.child_relid, channel->target_cpu);
spin_lock_irqsave(&channel->lock, flags);
list_for_each(cur, &channel->sc_list) { list_for_each(cur, &channel->sc_list) {
if (tot_written >= buf_size - 1) if (tot_written >= buf_size - 1)
break; break;
...@@ -533,7 +531,7 @@ static ssize_t channel_vp_mapping_show(struct device *dev, ...@@ -533,7 +531,7 @@ static ssize_t channel_vp_mapping_show(struct device *dev,
tot_written += n_written; tot_written += n_written;
} }
spin_unlock_irqrestore(&channel->lock, flags); mutex_unlock(&vmbus_connection.channel_mutex);
return tot_written; return tot_written;
} }
...@@ -1717,7 +1715,7 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel, ...@@ -1717,7 +1715,7 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel,
/* No CPUs should come up or down during this. */ /* No CPUs should come up or down during this. */
cpus_read_lock(); cpus_read_lock();
if (!cpumask_test_cpu(target_cpu, cpu_online_mask)) { if (!cpu_online(target_cpu)) {
cpus_read_unlock(); cpus_read_unlock();
return -EINVAL; return -EINVAL;
} }
...@@ -1779,8 +1777,6 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel, ...@@ -1779,8 +1777,6 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel,
*/ */
channel->target_cpu = target_cpu; 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(). */ /* See init_vp_index(). */
if (hv_is_perf_channel(channel)) if (hv_is_perf_channel(channel))
...@@ -2347,7 +2343,6 @@ static int vmbus_acpi_add(struct acpi_device *device) ...@@ -2347,7 +2343,6 @@ static int vmbus_acpi_add(struct acpi_device *device)
static int vmbus_bus_suspend(struct device *dev) static int vmbus_bus_suspend(struct device *dev)
{ {
struct vmbus_channel *channel, *sc; struct vmbus_channel *channel, *sc;
unsigned long flags;
while (atomic_read(&vmbus_connection.offer_in_progress) != 0) { while (atomic_read(&vmbus_connection.offer_in_progress) != 0) {
/* /*
...@@ -2405,12 +2400,10 @@ static int vmbus_bus_suspend(struct device *dev) ...@@ -2405,12 +2400,10 @@ static int vmbus_bus_suspend(struct device *dev)
continue; continue;
} }
spin_lock_irqsave(&channel->lock, flags);
list_for_each_entry(sc, &channel->sc_list, sc_list) { list_for_each_entry(sc, &channel->sc_list, sc_list) {
pr_err("Sub-channel not deleted!\n"); pr_err("Sub-channel not deleted!\n");
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
} }
spin_unlock_irqrestore(&channel->lock, flags);
atomic_inc(&vmbus_connection.nr_chan_fixup_on_resume); atomic_inc(&vmbus_connection.nr_chan_fixup_on_resume);
} }
......
...@@ -462,6 +462,11 @@ struct storvsc_device { ...@@ -462,6 +462,11 @@ struct storvsc_device {
* Mask of CPUs bound to subchannels. * Mask of CPUs bound to subchannels.
*/ */
struct cpumask alloced_cpus; 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 */ /* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request; struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request; struct storvsc_cmd_request reset_request;
...@@ -639,7 +644,7 @@ static void storvsc_change_target_cpu(struct vmbus_channel *channel, u32 old, ...@@ -639,7 +644,7 @@ static void storvsc_change_target_cpu(struct vmbus_channel *channel, u32 old,
return; return;
/* See storvsc_do_io() -> get_og_chn(). */ /* 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 * Determines if the storvsc device has other channels assigned to
...@@ -676,7 +681,7 @@ static void storvsc_change_target_cpu(struct vmbus_channel *channel, u32 old, ...@@ -676,7 +681,7 @@ static void storvsc_change_target_cpu(struct vmbus_channel *channel, u32 old,
WRITE_ONCE(stor_device->stor_chns[new], channel); WRITE_ONCE(stor_device->stor_chns[new], channel);
cpumask_set_cpu(new, &stor_device->alloced_cpus); 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) static void handle_sc_creation(struct vmbus_channel *new_sc)
...@@ -1433,14 +1438,14 @@ static int storvsc_do_io(struct hv_device *device, ...@@ -1433,14 +1438,14 @@ static int storvsc_do_io(struct hv_device *device,
} }
} }
} else { } else {
spin_lock_irqsave(&device->channel->lock, flags); spin_lock_irqsave(&stor_device->lock, flags);
outgoing_channel = stor_device->stor_chns[q_num]; outgoing_channel = stor_device->stor_chns[q_num];
if (outgoing_channel != NULL) { if (outgoing_channel != NULL) {
spin_unlock_irqrestore(&device->channel->lock, flags); spin_unlock_irqrestore(&stor_device->lock, flags);
goto found_channel; goto found_channel;
} }
outgoing_channel = get_og_chn(stor_device, q_num); 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: found_channel:
...@@ -1881,6 +1886,7 @@ static int storvsc_probe(struct hv_device *device, ...@@ -1881,6 +1886,7 @@ static int storvsc_probe(struct hv_device *device,
init_waitqueue_head(&stor_device->waiting_to_drain); init_waitqueue_head(&stor_device->waiting_to_drain);
stor_device->device = device; stor_device->device = device;
stor_device->host = host; stor_device->host = host;
spin_lock_init(&stor_device->lock);
hv_set_drvdata(device, stor_device); hv_set_drvdata(device, stor_device);
stor_device->port_number = host->host_no; stor_device->port_number = host->host_no;
......
...@@ -803,17 +803,15 @@ struct vmbus_channel { ...@@ -803,17 +803,15 @@ struct vmbus_channel {
u64 sig_event; u64 sig_event;
/* /*
* Starting with win8, this field will be used to specify * Starting with win8, this field will be used to specify the
* the target virtual processor on which to deliver the interrupt for * target CPU on which to deliver the interrupt for the host
* the host to guest communication. * to guest communication.
* Prior to win8, incoming channel interrupts would only *
* be delivered on cpu 0. Setting this value to 0 would * Prior to win8, incoming channel interrupts would only be
* preserve the earlier behavior. * 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; u32 target_cpu;
int numa_node;
/* /*
* Support for sub-channels. For high performance devices, * Support for sub-channels. For high performance devices,
* it will be useful to have multiple sub-channels to support * it will be useful to have multiple sub-channels to support
...@@ -842,12 +840,6 @@ struct vmbus_channel { ...@@ -842,12 +840,6 @@ struct vmbus_channel {
*/ */
void (*chn_rescind_callback)(struct vmbus_channel *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. * All Sub-channels of a primary channel are linked here.
*/ */
......
...@@ -219,7 +219,7 @@ struct hv_do_fcopy { ...@@ -219,7 +219,7 @@ struct hv_do_fcopy {
* kernel and user-level daemon communicate using a connector channel. * kernel and user-level daemon communicate using a connector channel.
* *
* The user mode component first registers with the * 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 * 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 * 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. * sequence field in the cn_msg header to define our KVP message types.
......
...@@ -437,7 +437,7 @@ void kvp_get_os_info(void) ...@@ -437,7 +437,7 @@ void kvp_get_os_info(void)
/* /*
* Parse the /etc/os-release file if present: * 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"); file = fopen("/etc/os-release", "r");
if (file != NULL) { if (file != NULL) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment