aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-12-10 03:22:34 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-12-10 03:22:34 -0500
commitc4aa8b2a8b63a269d63acafc0358a7b9f5d9e563 (patch)
treed04a7861e542665bb7c03aac729a72c957be8abc /drivers/hv
parent48d365de7746a000afd7f9f7cc1821cbb6fe9b45 (diff)
parent40e020c129cfc991e8ab4736d2665351ffd1468d (diff)
Merge 4.20-rc6 into char-misc-next
This should resolve the hv driver merge conflict. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/channel_mgmt.c188
-rw-r--r--drivers/hv/connection.c24
-rw-r--r--drivers/hv/hyperv_vmbus.h7
3 files changed, 154 insertions, 65 deletions
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 82e673671087..d01689079e9b 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -434,60 +434,16 @@ void vmbus_free_channels(void)
434 } 434 }
435} 435}
436 436
437/* 437/* Note: the function can run concurrently for primary/sub channels. */
438 * vmbus_process_offer - Process the offer by creating a channel/device 438static void vmbus_add_channel_work(struct work_struct *work)
439 * associated with this offer
440 */
441static void vmbus_process_offer(struct vmbus_channel *newchannel)
442{ 439{
443 struct vmbus_channel *channel; 440 struct vmbus_channel *newchannel =
444 bool fnew = true; 441 container_of(work, struct vmbus_channel, add_channel_work);
442 struct vmbus_channel *primary_channel = newchannel->primary_channel;
445 unsigned long flags; 443 unsigned long flags;
446 u16 dev_type; 444 u16 dev_type;
447 int ret; 445 int ret;
448 446
449 /* Make sure this is a new offer */
450 mutex_lock(&vmbus_connection.channel_mutex);
451
452 /*
453 * Now that we have acquired the channel_mutex,
454 * we can release the potentially racing rescind thread.
455 */
456 atomic_dec(&vmbus_connection.offer_in_progress);
457
458 list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
459 if (!uuid_le_cmp(channel->offermsg.offer.if_type,
460 newchannel->offermsg.offer.if_type) &&
461 !uuid_le_cmp(channel->offermsg.offer.if_instance,
462 newchannel->offermsg.offer.if_instance)) {
463 fnew = false;
464 break;
465 }
466 }
467
468 if (fnew)
469 list_add_tail(&newchannel->listentry,
470 &vmbus_connection.chn_list);
471
472 mutex_unlock(&vmbus_connection.channel_mutex);
473
474 if (!fnew) {
475 /*
476 * Check to see if this is a sub-channel.
477 */
478 if (newchannel->offermsg.offer.sub_channel_index != 0) {
479 /*
480 * Process the sub-channel.
481 */
482 newchannel->primary_channel = channel;
483 spin_lock_irqsave(&channel->lock, flags);
484 list_add_tail(&newchannel->sc_list, &channel->sc_list);
485 spin_unlock_irqrestore(&channel->lock, flags);
486 } else {
487 goto err_free_chan;
488 }
489 }
490
491 dev_type = hv_get_dev_type(newchannel); 447 dev_type = hv_get_dev_type(newchannel);
492 448
493 init_vp_index(newchannel, dev_type); 449 init_vp_index(newchannel, dev_type);
@@ -505,27 +461,26 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
505 /* 461 /*
506 * This state is used to indicate a successful open 462 * This state is used to indicate a successful open
507 * so that when we do close the channel normally, we 463 * so that when we do close the channel normally, we
508 * can cleanup properly 464 * can cleanup properly.
509 */ 465 */
510 newchannel->state = CHANNEL_OPEN_STATE; 466 newchannel->state = CHANNEL_OPEN_STATE;
511 467
512 if (!fnew) { 468 if (primary_channel != NULL) {
513 struct hv_device *dev 469 /* newchannel is a sub-channel. */
514 = newchannel->primary_channel->device_obj; 470 struct hv_device *dev = primary_channel->device_obj;
515 471
516 if (vmbus_add_channel_kobj(dev, newchannel)) 472 if (vmbus_add_channel_kobj(dev, newchannel))
517 goto err_free_chan; 473 goto err_deq_chan;
474
475 if (primary_channel->sc_creation_callback != NULL)
476 primary_channel->sc_creation_callback(newchannel);
518 477
519 if (channel->sc_creation_callback != NULL)
520 channel->sc_creation_callback(newchannel);
521 newchannel->probe_done = true; 478 newchannel->probe_done = true;
522 return; 479 return;
523 } 480 }
524 481
525 /* 482 /*
526 * Start the process of binding this offer to the driver 483 * Start the process of binding the primary channel to the driver
527 * We need to set the DeviceObject field before calling
528 * vmbus_child_dev_add()
529 */ 484 */
530 newchannel->device_obj = vmbus_device_create( 485 newchannel->device_obj = vmbus_device_create(
531 &newchannel->offermsg.offer.if_type, 486 &newchannel->offermsg.offer.if_type,
@@ -554,13 +509,28 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
554 509
555err_deq_chan: 510err_deq_chan:
556 mutex_lock(&vmbus_connection.channel_mutex); 511 mutex_lock(&vmbus_connection.channel_mutex);
557 list_del(&newchannel->listentry); 512
513 /*
514 * We need to set the flag, otherwise
515 * vmbus_onoffer_rescind() can be blocked.
516 */
517 newchannel->probe_done = true;
518
519 if (primary_channel == NULL) {
520 list_del(&newchannel->listentry);
521 } else {
522 spin_lock_irqsave(&primary_channel->lock, flags);
523 list_del(&newchannel->sc_list);
524 spin_unlock_irqrestore(&primary_channel->lock, flags);
525 }
526
558 mutex_unlock(&vmbus_connection.channel_mutex); 527 mutex_unlock(&vmbus_connection.channel_mutex);
559 528
560 if (newchannel->target_cpu != get_cpu()) { 529 if (newchannel->target_cpu != get_cpu()) {
561 put_cpu(); 530 put_cpu();
562 smp_call_function_single(newchannel->target_cpu, 531 smp_call_function_single(newchannel->target_cpu,
563 percpu_channel_deq, newchannel, true); 532 percpu_channel_deq,
533 newchannel, true);
564 } else { 534 } else {
565 percpu_channel_deq(newchannel); 535 percpu_channel_deq(newchannel);
566 put_cpu(); 536 put_cpu();
@@ -568,14 +538,104 @@ err_deq_chan:
568 538
569 vmbus_release_relid(newchannel->offermsg.child_relid); 539 vmbus_release_relid(newchannel->offermsg.child_relid);
570 540
571err_free_chan:
572 free_channel(newchannel); 541 free_channel(newchannel);
573} 542}
574 543
575/* 544/*
545 * vmbus_process_offer - Process the offer by creating a channel/device
546 * associated with this offer
547 */
548static void vmbus_process_offer(struct vmbus_channel *newchannel)
549{
550 struct vmbus_channel *channel;
551 struct workqueue_struct *wq;
552 unsigned long flags;
553 bool fnew = true;
554
555 mutex_lock(&vmbus_connection.channel_mutex);
556
557 /*
558 * Now that we have acquired the channel_mutex,
559 * we can release the potentially racing rescind thread.
560 */
561 atomic_dec(&vmbus_connection.offer_in_progress);
562
563 list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
564 if (!uuid_le_cmp(channel->offermsg.offer.if_type,
565 newchannel->offermsg.offer.if_type) &&
566 !uuid_le_cmp(channel->offermsg.offer.if_instance,
567 newchannel->offermsg.offer.if_instance)) {
568 fnew = false;
569 break;
570 }
571 }
572
573 if (fnew)
574 list_add_tail(&newchannel->listentry,
575 &vmbus_connection.chn_list);
576 else {
577 /*
578 * Check to see if this is a valid sub-channel.
579 */
580 if (newchannel->offermsg.offer.sub_channel_index == 0) {
581 mutex_unlock(&vmbus_connection.channel_mutex);
582 /*
583 * Don't call free_channel(), because newchannel->kobj
584 * is not initialized yet.
585 */
586 kfree(newchannel);
587 WARN_ON_ONCE(1);
588 return;
589 }
590 /*
591 * Process the sub-channel.
592 */
593 newchannel->primary_channel = channel;
594 spin_lock_irqsave(&channel->lock, flags);
595 list_add_tail(&newchannel->sc_list, &channel->sc_list);
596 spin_unlock_irqrestore(&channel->lock, flags);
597 }
598
599 mutex_unlock(&vmbus_connection.channel_mutex);
600
601 /*
602 * vmbus_process_offer() mustn't call channel->sc_creation_callback()
603 * directly for sub-channels, because sc_creation_callback() ->
604 * vmbus_open() may never get the host's response to the
605 * OPEN_CHANNEL message (the host may rescind a channel at any time,
606 * e.g. in the case of hot removing a NIC), and vmbus_onoffer_rescind()
607 * may not wake up the vmbus_open() as it's blocked due to a non-zero
608 * vmbus_connection.offer_in_progress, and finally we have a deadlock.
609 *
610 * The above is also true for primary channels, if the related device
611 * drivers use sync probing mode by default.
612 *
613 * And, usually the handling of primary channels and sub-channels can
614 * depend on each other, so we should offload them to different
615 * workqueues to avoid possible deadlock, e.g. in sync-probing mode,
616 * NIC1's netvsc_subchan_work() can race with NIC2's netvsc_probe() ->
617 * rtnl_lock(), and causes deadlock: the former gets the rtnl_lock
618 * and waits for all the sub-channels to appear, but the latter
619 * can't get the rtnl_lock and this blocks the handling of
620 * sub-channels.
621 */
622 INIT_WORK(&newchannel->add_channel_work, vmbus_add_channel_work);
623 wq = fnew ? vmbus_connection.handle_primary_chan_wq :
624 vmbus_connection.handle_sub_chan_wq;
625 queue_work(wq, &newchannel->add_channel_work);
626}
627
628/*
576 * We use this state to statically distribute the channel interrupt load. 629 * We use this state to statically distribute the channel interrupt load.
577 */ 630 */
578static int next_numa_node_id; 631static int next_numa_node_id;
632/*
633 * init_vp_index() accesses global variables like next_numa_node_id, and
634 * it can run concurrently for primary channels and sub-channels: see
635 * vmbus_process_offer(), so we need the lock to protect the global
636 * variables.
637 */
638static DEFINE_SPINLOCK(bind_channel_to_cpu_lock);
579 639
580/* 640/*
581 * Starting with Win8, we can statically distribute the incoming 641 * Starting with Win8, we can statically distribute the incoming
@@ -611,6 +671,8 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
611 return; 671 return;
612 } 672 }
613 673
674 spin_lock(&bind_channel_to_cpu_lock);
675
614 /* 676 /*
615 * Based on the channel affinity policy, we will assign the NUMA 677 * Based on the channel affinity policy, we will assign the NUMA
616 * nodes. 678 * nodes.
@@ -693,6 +755,8 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
693 channel->target_cpu = cur_cpu; 755 channel->target_cpu = cur_cpu;
694 channel->target_vp = hv_cpu_number_to_vp_number(cur_cpu); 756 channel->target_vp = hv_cpu_number_to_vp_number(cur_cpu);
695 757
758 spin_unlock(&bind_channel_to_cpu_lock);
759
696 free_cpumask_var(available_mask); 760 free_cpumask_var(available_mask);
697} 761}
698 762
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index f4d08c8ac7f8..4fe117b761ce 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -190,6 +190,20 @@ int vmbus_connect(void)
190 goto cleanup; 190 goto cleanup;
191 } 191 }
192 192
193 vmbus_connection.handle_primary_chan_wq =
194 create_workqueue("hv_pri_chan");
195 if (!vmbus_connection.handle_primary_chan_wq) {
196 ret = -ENOMEM;
197 goto cleanup;
198 }
199
200 vmbus_connection.handle_sub_chan_wq =
201 create_workqueue("hv_sub_chan");
202 if (!vmbus_connection.handle_sub_chan_wq) {
203 ret = -ENOMEM;
204 goto cleanup;
205 }
206
193 INIT_LIST_HEAD(&vmbus_connection.chn_msg_list); 207 INIT_LIST_HEAD(&vmbus_connection.chn_msg_list);
194 spin_lock_init(&vmbus_connection.channelmsg_lock); 208 spin_lock_init(&vmbus_connection.channelmsg_lock);
195 209
@@ -280,10 +294,14 @@ void vmbus_disconnect(void)
280 */ 294 */
281 vmbus_initiate_unload(false); 295 vmbus_initiate_unload(false);
282 296
283 if (vmbus_connection.work_queue) { 297 if (vmbus_connection.handle_sub_chan_wq)
284 drain_workqueue(vmbus_connection.work_queue); 298 destroy_workqueue(vmbus_connection.handle_sub_chan_wq);
299
300 if (vmbus_connection.handle_primary_chan_wq)
301 destroy_workqueue(vmbus_connection.handle_primary_chan_wq);
302
303 if (vmbus_connection.work_queue)
285 destroy_workqueue(vmbus_connection.work_queue); 304 destroy_workqueue(vmbus_connection.work_queue);
286 }
287 305
288 if (vmbus_connection.int_page) { 306 if (vmbus_connection.int_page) {
289 free_pages((unsigned long)vmbus_connection.int_page, 0); 307 free_pages((unsigned long)vmbus_connection.int_page, 0);
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index f17c06a5e74b..313a07f5efa1 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -333,7 +333,14 @@ struct vmbus_connection {
333 struct list_head chn_list; 333 struct list_head chn_list;
334 struct mutex channel_mutex; 334 struct mutex channel_mutex;
335 335
336 /*
337 * An offer message is handled first on the work_queue, and then
338 * is further handled on handle_primary_chan_wq or
339 * handle_sub_chan_wq.
340 */
336 struct workqueue_struct *work_queue; 341 struct workqueue_struct *work_queue;
342 struct workqueue_struct *handle_primary_chan_wq;
343 struct workqueue_struct *handle_sub_chan_wq;
337}; 344};
338 345
339 346