Commit 9ab9bc51 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -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);
+6 −25
Original line number Diff line number Diff line
@@ -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);
}
+0 −3
Original line number Diff line number Diff line
@@ -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;
	}
+5 −12
Original line number Diff line number Diff line
@@ -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);
	}
+11 −5
Original line number Diff line number Diff line
@@ -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;
Loading