Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+34 -68
+3 -6
drivers/hv/channel.c
··· 18 18 #include <linux/uio.h> 19 19 #include <linux/interrupt.h> 20 20 #include <asm/page.h> 21 + #include <asm/mshyperv.h> 21 22 22 23 #include "hyperv_vmbus.h" 23 24 ··· 129 128 send_pages = newchannel->ringbuffer_send_offset; 130 129 recv_pages = newchannel->ringbuffer_pagecount - send_pages; 131 130 132 - spin_lock_irqsave(&newchannel->lock, flags); 133 - if (newchannel->state != CHANNEL_OPEN_STATE) { 134 - spin_unlock_irqrestore(&newchannel->lock, flags); 131 + if (newchannel->state != CHANNEL_OPEN_STATE) 135 132 return -EINVAL; 136 - } 137 - spin_unlock_irqrestore(&newchannel->lock, flags); 138 133 139 134 newchannel->state = CHANNEL_OPENING_STATE; 140 135 newchannel->onchannel_callback = onchannelcallback; ··· 173 176 open_msg->child_relid = newchannel->offermsg.child_relid; 174 177 open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; 175 178 open_msg->downstream_ringbuffer_pageoffset = newchannel->ringbuffer_send_offset; 176 - open_msg->target_vp = newchannel->target_vp; 179 + open_msg->target_vp = hv_cpu_number_to_vp_number(newchannel->target_cpu); 177 180 178 181 if (userdatalen) 179 182 memcpy(open_msg->userdata, userdata, userdatalen);
+6 -25
drivers/hv/channel_mgmt.c
··· 317 317 return NULL; 318 318 319 319 spin_lock_init(&channel->sched_lock); 320 - spin_lock_init(&channel->lock); 321 320 init_completion(&channel->rescind_event); 322 321 323 322 INIT_LIST_HEAD(&channel->sc_list); ··· 399 400 400 401 void hv_process_channel_removal(struct vmbus_channel *channel) 401 402 { 402 - unsigned long flags; 403 - 404 403 lockdep_assert_held(&vmbus_connection.channel_mutex); 405 404 BUG_ON(!channel->rescind); 406 405 ··· 419 422 if (channel->offermsg.child_relid != INVALID_RELID) 420 423 vmbus_channel_unmap_relid(channel); 421 424 422 - if (channel->primary_channel == NULL) { 425 + if (channel->primary_channel == NULL) 423 426 list_del(&channel->listentry); 424 - } else { 425 - struct vmbus_channel *primary_channel = channel->primary_channel; 426 - spin_lock_irqsave(&primary_channel->lock, flags); 427 + else 427 428 list_del(&channel->sc_list); 428 - spin_unlock_irqrestore(&primary_channel->lock, flags); 429 - } 430 429 431 430 /* 432 431 * If this is a "perf" channel, updates the hv_numa_map[] masks so that ··· 463 470 struct vmbus_channel *newchannel = 464 471 container_of(work, struct vmbus_channel, add_channel_work); 465 472 struct vmbus_channel *primary_channel = newchannel->primary_channel; 466 - unsigned long flags; 467 473 int ret; 468 474 469 475 /* ··· 523 531 */ 524 532 newchannel->probe_done = true; 525 533 526 - if (primary_channel == NULL) { 534 + if (primary_channel == NULL) 527 535 list_del(&newchannel->listentry); 528 - } else { 529 - spin_lock_irqsave(&primary_channel->lock, flags); 536 + else 530 537 list_del(&newchannel->sc_list); 531 - spin_unlock_irqrestore(&primary_channel->lock, flags); 532 - } 533 538 534 539 /* vmbus_process_offer() has mapped the channel. */ 535 540 vmbus_channel_unmap_relid(newchannel); ··· 546 557 { 547 558 struct vmbus_channel *channel; 548 559 struct workqueue_struct *wq; 549 - unsigned long flags; 550 560 bool fnew = true; 551 561 552 562 /* ··· 597 609 } 598 610 } 599 611 600 - if (fnew) 612 + if (fnew) { 601 613 list_add_tail(&newchannel->listentry, 602 614 &vmbus_connection.chn_list); 603 - else { 615 + } else { 604 616 /* 605 617 * Check to see if this is a valid sub-channel. 606 618 */ ··· 618 630 * Process the sub-channel. 619 631 */ 620 632 newchannel->primary_channel = channel; 621 - spin_lock_irqsave(&channel->lock, flags); 622 633 list_add_tail(&newchannel->sc_list, &channel->sc_list); 623 - spin_unlock_irqrestore(&channel->lock, flags); 624 634 } 625 635 626 636 vmbus_channel_map_relid(newchannel); ··· 688 702 * In case alloc_cpumask_var() fails, bind it to 689 703 * VMBUS_CONNECT_CPU. 690 704 */ 691 - channel->numa_node = cpu_to_node(VMBUS_CONNECT_CPU); 692 705 channel->target_cpu = VMBUS_CONNECT_CPU; 693 - channel->target_vp = 694 - hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU); 695 706 if (perf_chn) 696 707 hv_set_alloced_cpu(VMBUS_CONNECT_CPU); 697 708 return; ··· 704 721 continue; 705 722 break; 706 723 } 707 - channel->numa_node = numa_node; 708 724 alloced_mask = &hv_context.hv_numa_map[numa_node]; 709 725 710 726 if (cpumask_weight(alloced_mask) == ··· 721 739 cpumask_set_cpu(target_cpu, alloced_mask); 722 740 723 741 channel->target_cpu = target_cpu; 724 - channel->target_vp = hv_cpu_number_to_vp_number(target_cpu); 725 742 726 743 free_cpumask_var(available_mask); 727 744 }
-3
drivers/hv/hv.c
··· 241 241 { 242 242 struct vmbus_channel *channel, *sc; 243 243 bool channel_found = false; 244 - unsigned long flags; 245 244 246 245 /* 247 246 * Hyper-V does not provide a way to change the connect CPU once ··· 262 263 channel_found = true; 263 264 break; 264 265 } 265 - spin_lock_irqsave(&channel->lock, flags); 266 266 list_for_each_entry(sc, &channel->sc_list, sc_list) { 267 267 if (sc->target_cpu == cpu) { 268 268 channel_found = true; 269 269 break; 270 270 } 271 271 } 272 - spin_unlock_irqrestore(&channel->lock, flags); 273 272 if (channel_found) 274 273 break; 275 274 }
+5 -12
drivers/hv/vmbus_drv.c
··· 23 23 #include <linux/cpu.h> 24 24 #include <linux/sched/task_stack.h> 25 25 26 - #include <asm/mshyperv.h> 27 26 #include <linux/delay.h> 28 27 #include <linux/notifier.h> 29 28 #include <linux/ptrace.h> ··· 226 227 if (!hv_dev->channel) 227 228 return -ENODEV; 228 229 229 - return sprintf(buf, "%d\n", hv_dev->channel->numa_node); 230 + return sprintf(buf, "%d\n", cpu_to_node(hv_dev->channel->target_cpu)); 230 231 } 231 232 static DEVICE_ATTR_RO(numa_node); 232 233 #endif ··· 507 508 { 508 509 struct hv_device *hv_dev = device_to_hv_device(dev); 509 510 struct vmbus_channel *channel = hv_dev->channel, *cur_sc; 510 - unsigned long flags; 511 511 int buf_size = PAGE_SIZE, n_written, tot_written; 512 512 struct list_head *cur; 513 513 514 514 if (!channel) 515 515 return -ENODEV; 516 516 517 + mutex_lock(&vmbus_connection.channel_mutex); 518 + 517 519 tot_written = snprintf(buf, buf_size, "%u:%u\n", 518 520 channel->offermsg.child_relid, channel->target_cpu); 519 - 520 - spin_lock_irqsave(&channel->lock, flags); 521 521 522 522 list_for_each(cur, &channel->sc_list) { 523 523 if (tot_written >= buf_size - 1) ··· 531 533 tot_written += n_written; 532 534 } 533 535 534 - spin_unlock_irqrestore(&channel->lock, flags); 536 + mutex_unlock(&vmbus_connection.channel_mutex); 535 537 536 538 return tot_written; 537 539 } ··· 1715 1717 /* No CPUs should come up or down during this. */ 1716 1718 cpus_read_lock(); 1717 1719 1718 - if (!cpumask_test_cpu(target_cpu, cpu_online_mask)) { 1720 + if (!cpu_online(target_cpu)) { 1719 1721 cpus_read_unlock(); 1720 1722 return -EINVAL; 1721 1723 } ··· 1777 1779 */ 1778 1780 1779 1781 channel->target_cpu = target_cpu; 1780 - channel->target_vp = hv_cpu_number_to_vp_number(target_cpu); 1781 - channel->numa_node = cpu_to_node(target_cpu); 1782 1782 1783 1783 /* See init_vp_index(). */ 1784 1784 if (hv_is_perf_channel(channel)) ··· 2343 2347 static int vmbus_bus_suspend(struct device *dev) 2344 2348 { 2345 2349 struct vmbus_channel *channel, *sc; 2346 - unsigned long flags; 2347 2350 2348 2351 while (atomic_read(&vmbus_connection.offer_in_progress) != 0) { 2349 2352 /* ··· 2400 2405 continue; 2401 2406 } 2402 2407 2403 - spin_lock_irqsave(&channel->lock, flags); 2404 2408 list_for_each_entry(sc, &channel->sc_list, sc_list) { 2405 2409 pr_err("Sub-channel not deleted!\n"); 2406 2410 WARN_ON_ONCE(1); 2407 2411 } 2408 - spin_unlock_irqrestore(&channel->lock, flags); 2409 2412 2410 2413 atomic_inc(&vmbus_connection.nr_chan_fixup_on_resume); 2411 2414 }
+11 -5
drivers/scsi/storvsc_drv.c
··· 462 462 * Mask of CPUs bound to subchannels. 463 463 */ 464 464 struct cpumask alloced_cpus; 465 + /* 466 + * Serializes modifications of stor_chns[] from storvsc_do_io() 467 + * and storvsc_change_target_cpu(). 468 + */ 469 + spinlock_t lock; 465 470 /* Used for vsc/vsp channel reset process */ 466 471 struct storvsc_cmd_request init_request; 467 472 struct storvsc_cmd_request reset_request; ··· 644 639 return; 645 640 646 641 /* See storvsc_do_io() -> get_og_chn(). */ 647 - spin_lock_irqsave(&device->channel->lock, flags); 642 + spin_lock_irqsave(&stor_device->lock, flags); 648 643 649 644 /* 650 645 * Determines if the storvsc device has other channels assigned to ··· 681 676 WRITE_ONCE(stor_device->stor_chns[new], channel); 682 677 cpumask_set_cpu(new, &stor_device->alloced_cpus); 683 678 684 - spin_unlock_irqrestore(&device->channel->lock, flags); 679 + spin_unlock_irqrestore(&stor_device->lock, flags); 685 680 } 686 681 687 682 static void handle_sc_creation(struct vmbus_channel *new_sc) ··· 1438 1433 } 1439 1434 } 1440 1435 } else { 1441 - spin_lock_irqsave(&device->channel->lock, flags); 1436 + spin_lock_irqsave(&stor_device->lock, flags); 1442 1437 outgoing_channel = stor_device->stor_chns[q_num]; 1443 1438 if (outgoing_channel != NULL) { 1444 - spin_unlock_irqrestore(&device->channel->lock, flags); 1439 + spin_unlock_irqrestore(&stor_device->lock, flags); 1445 1440 goto found_channel; 1446 1441 } 1447 1442 outgoing_channel = get_og_chn(stor_device, q_num); 1448 - spin_unlock_irqrestore(&device->channel->lock, flags); 1443 + spin_unlock_irqrestore(&stor_device->lock, flags); 1449 1444 } 1450 1445 1451 1446 found_channel: ··· 1886 1881 init_waitqueue_head(&stor_device->waiting_to_drain); 1887 1882 stor_device->device = device; 1888 1883 stor_device->host = host; 1884 + spin_lock_init(&stor_device->lock); 1889 1885 hv_set_drvdata(device, stor_device); 1890 1886 1891 1887 stor_device->port_number = host->host_no;
+7 -15
include/linux/hyperv.h
··· 803 803 u64 sig_event; 804 804 805 805 /* 806 - * Starting with win8, this field will be used to specify 807 - * the target virtual processor on which to deliver the interrupt for 808 - * the host to guest communication. 809 - * Prior to win8, incoming channel interrupts would only 810 - * be delivered on cpu 0. Setting this value to 0 would 811 - * preserve the earlier behavior. 806 + * Starting with win8, this field will be used to specify the 807 + * target CPU on which to deliver the interrupt for the host 808 + * to guest communication. 809 + * 810 + * Prior to win8, incoming channel interrupts would only be 811 + * delivered on CPU 0. Setting this value to 0 would preserve 812 + * the earlier behavior. 812 813 */ 813 - u32 target_vp; 814 - /* The corresponding CPUID in the guest */ 815 814 u32 target_cpu; 816 - int numa_node; 817 815 /* 818 816 * Support for sub-channels. For high performance devices, 819 817 * it will be useful to have multiple sub-channels to support ··· 840 842 */ 841 843 void (*chn_rescind_callback)(struct vmbus_channel *channel); 842 844 843 - /* 844 - * The spinlock to protect the structure. It is being used to protect 845 - * test-and-set access to various attributes of the structure as well 846 - * as all sc_list operations. 847 - */ 848 - spinlock_t lock; 849 845 /* 850 846 * All Sub-channels of a primary channel are linked here. 851 847 */
+1 -1
include/uapi/linux/hyperv.h
··· 219 219 * kernel and user-level daemon communicate using a connector channel. 220 220 * 221 221 * The user mode component first registers with the 222 - * the kernel component. Subsequently, the kernel component requests, data 222 + * kernel component. Subsequently, the kernel component requests, data 223 223 * for the specified keys. In response to this message the user mode component 224 224 * fills in the value corresponding to the specified key. We overload the 225 225 * sequence field in the cn_msg header to define our KVP message types.
+1 -1
tools/hv/hv_kvp_daemon.c
··· 437 437 438 438 /* 439 439 * Parse the /etc/os-release file if present: 440 - * http://www.freedesktop.org/software/systemd/man/os-release.html 440 + * https://www.freedesktop.org/software/systemd/man/os-release.html 441 441 */ 442 442 file = fopen("/etc/os-release", "r"); 443 443 if (file != NULL) {