History

Drivers: hv: vmbus: Remove the unused HV_LOCALIZED channel affinity logic

The logic is unused since commit 509879bdb30b8 ("Drivers: hv: Introduce a policy for controlling channel affinity"). This logic assumes that a channel target_cpu doesn't change during the lifetime of a channel, but this assumption is incompatible with the new functionality that allows changing the vCPU a channel will interrupt.

Andrea Parri (Microsoft) committed 6 years ago

Commit 8ef4c4a1 parent 240ad772 files · +25 −107Browse files

Unified · Split

2 files
  1. drivers/hv/channel_mgmt.c +25 −80
  2. include/linux/hyperv.h +0 −27
drivers/hv/channel_mgmt.c+25−80
@@ -433,14 +433,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel) · 432 unmodified lines
433 spin_unlock_irqrestore(&primary_channel->lock, flags);433 spin_unlock_irqrestore(&primary_channel->lock, flags);
434 }434 }
435 435
436 /*
437 * We need to free the bit for init_vp_index() to work in the case
438 * of sub-channel, when we reload drivers like hv_netvsc.
439 */
440 if (channel->affinity_policy == HV_LOCALIZED)
441 cpumask_clear_cpu(channel->target_cpu,
442 &primary_channel->alloced_cpus_in_node);
443
444 /*436 /*
445 * Upon suspend, an in-use hv_sock channel is marked as "rescinded" and437 * Upon suspend, an in-use hv_sock channel is marked as "rescinded" and
446 * the relid is invalidated; after hibernation, when the user-space app438 * the relid is invalidated; after hibernation, when the user-space app
@@ -662,20 +654,21 @@ static DEFINE_SPINLOCK(bind_channel_to_cpu_lock); · 215 unmodified lines
662/*654/*
663 * Starting with Win8, we can statically distribute the incoming655 * Starting with Win8, we can statically distribute the incoming
664 * channel interrupt load by binding a channel to VCPU.656 * channel interrupt load by binding a channel to VCPU.
665 * We distribute the interrupt loads to one or more NUMA nodes based on
666 * the channel's affinity_policy.
667 *657 *
668 * For pre-win8 hosts or non-performance critical channels we assign the658 * For pre-win8 hosts or non-performance critical channels we assign the
669 * first CPU in the first NUMA node.659 * first CPU in the first NUMA node.
660 *
661 * Starting with win8, performance critical channels will be distributed
662 * evenly among all the available NUMA nodes. Once the node is assigned,
663 * we will assign the CPU based on a simple round robin scheme.
670 */664 */
671static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)665static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
672{666{
673 u32 cur_cpu;
674 bool perf_chn = vmbus_devs[dev_type].perf_device;667 bool perf_chn = vmbus_devs[dev_type].perf_device;
675 struct vmbus_channel *primary = channel->primary_channel;
676 int next_node;
677 cpumask_var_t available_mask;668 cpumask_var_t available_mask;
678 struct cpumask *alloced_mask;669 struct cpumask *alloced_mask;
670 u32 target_cpu;
671 int numa_node;
679 672
680 if ((vmbus_proto_version == VERSION_WS2008) ||673 if ((vmbus_proto_version == VERSION_WS2008) ||
681 (vmbus_proto_version == VERSION_WIN7) || (!perf_chn) ||674 (vmbus_proto_version == VERSION_WIN7) || (!perf_chn) ||
@@ -693,31 +686,27 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type) · 11 unmodified lines
693 return;686 return;
694 }687 }
695 688
696 spin_lock(&bind_channel_to_cpu_lock);
697
698 /*689 /*
699 * Based on the channel affinity policy, we will assign the NUMA690 * Serializes the accesses to the global variable next_numa_node_id.
700 * nodes.691 * See also the header comment of the spin lock declaration.
701 */692 */
693 spin_lock(&bind_channel_to_cpu_lock);
702 694
703 if ((channel->affinity_policy == HV_BALANCED) || (!primary)) {695 while (true) {
704 while (true) {696 numa_node = next_numa_node_id++;
705 next_node = next_numa_node_id++;697 if (numa_node == nr_node_ids) {
706 if (next_node == nr_node_ids) {698 next_numa_node_id = 0;
707 next_node = next_numa_node_id = 0;699 continue;
708 continue;
709 }
710 if (cpumask_empty(cpumask_of_node(next_node)))
711 continue;
712 break;
713 }700 }
714 channel->numa_node = next_node;701 if (cpumask_empty(cpumask_of_node(numa_node)))
715 primary = channel;702 continue;
703 break;
716 }704 }
717 alloced_mask = &hv_context.hv_numa_map[primary->numa_node];705 channel->numa_node = numa_node;
706 alloced_mask = &hv_context.hv_numa_map[numa_node];
718 707
719 if (cpumask_weight(alloced_mask) ==708 if (cpumask_weight(alloced_mask) ==
720 cpumask_weight(cpumask_of_node(primary->numa_node))) {709 cpumask_weight(cpumask_of_node(numa_node))) {
721 /*710 /*
722 * We have cycled through all the CPUs in the node;711 * We have cycled through all the CPUs in the node;
723 * reset the alloced map.712 * reset the alloced map.
@@ -725,57 +714,13 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type) · 1 unmodified line
725 cpumask_clear(alloced_mask);714 cpumask_clear(alloced_mask);
726 }715 }
727 716
728 cpumask_xor(available_mask, alloced_mask,717 cpumask_xor(available_mask, alloced_mask, cpumask_of_node(numa_node));
729 cpumask_of_node(primary->numa_node));
730 718
731 cur_cpu = -1;719 target_cpu = cpumask_first(available_mask);
732 720 cpumask_set_cpu(target_cpu, alloced_mask);
733 if (primary->affinity_policy == HV_LOCALIZED) {
734 /*
735 * Normally Hyper-V host doesn't create more subchannels
736 * than there are VCPUs on the node but it is possible when not
737 * all present VCPUs on the node are initialized by guest.
738 * Clear the alloced_cpus_in_node to start over.
739 */
740 if (cpumask_equal(&primary->alloced_cpus_in_node,
741 cpumask_of_node(primary->numa_node)))
742 cpumask_clear(&primary->alloced_cpus_in_node);
743 }
744
745 while (true) {
746 cur_cpu = cpumask_next(cur_cpu, available_mask);
747 if (cur_cpu >= nr_cpu_ids) {
748 cur_cpu = -1;
749 cpumask_copy(available_mask,
750 cpumask_of_node(primary->numa_node));
751 continue;
752 }
753
754 if (primary->affinity_policy == HV_LOCALIZED) {
755 /*
756 * NOTE: in the case of sub-channel, we clear the
757 * sub-channel related bit(s) in
758 * primary->alloced_cpus_in_node in
759 * hv_process_channel_removal(), so when we
760 * reload drivers like hv_netvsc in SMP guest, here
761 * we're able to re-allocate
762 * bit from primary->alloced_cpus_in_node.
763 */
764 if (!cpumask_test_cpu(cur_cpu,
765 &primary->alloced_cpus_in_node)) {
766 cpumask_set_cpu(cur_cpu,
767 &primary->alloced_cpus_in_node);
768 cpumask_set_cpu(cur_cpu, alloced_mask);
769 break;
770 }
771 } else {
772 cpumask_set_cpu(cur_cpu, alloced_mask);
773 break;
774 }
775 }
776 721
777 channel->target_cpu = cur_cpu;722 channel->target_cpu = target_cpu;
778 channel->target_vp = hv_cpu_number_to_vp_number(cur_cpu);723 channel->target_vp = hv_cpu_number_to_vp_number(target_cpu);
779 724
780 spin_unlock(&bind_channel_to_cpu_lock);725 spin_unlock(&bind_channel_to_cpu_lock);
781 726
include/linux/hyperv.h+0−27
@@ -689,11 +689,6 @@ union hv_connection_id { · 688 unmodified lines
689 } u;689 } u;
690};690};
691 691
692enum hv_numa_policy {
693 HV_BALANCED = 0,
694 HV_LOCALIZED,
695};
696
697enum vmbus_device_type {692enum vmbus_device_type {
698 HV_IDE = 0,693 HV_IDE = 0,
699 HV_SCSI,694 HV_SCSI,
@@ -808,10 +803,6 @@ struct vmbus_channel { · 108 unmodified lines
808 u32 target_vp;803 u32 target_vp;
809 /* The corresponding CPUID in the guest */804 /* The corresponding CPUID in the guest */
810 u32 target_cpu;805 u32 target_cpu;
811 /*
812 * State to manage the CPU affiliation of channels.
813 */
814 struct cpumask alloced_cpus_in_node;
815 int numa_node;806 int numa_node;
816 /*807 /*
817 * Support for sub-channels. For high performance devices,808 * Support for sub-channels. For high performance devices,
@@ -898,18 +889,6 @@ struct vmbus_channel { · 80 unmodified lines
898 */889 */
899 bool low_latency;890 bool low_latency;
900 891
901 /*
902 * NUMA distribution policy:
903 * We support two policies:
904 * 1) Balanced: Here all performance critical channels are
905 * distributed evenly amongst all the NUMA nodes.
906 * This policy will be the default policy.
907 * 2) Localized: All channels of a given instance of a
908 * performance critical service will be assigned CPUs
909 * within a selected NUMA node.
910 */
911 enum hv_numa_policy affinity_policy;
912
913 bool probe_done;892 bool probe_done;
914 893
915 /*894 /*
@@ -965,12 +944,6 @@ static inline bool is_sub_channel(const struct vmbus_channel *c) · 49 unmodified lines
965 return c->offermsg.offer.sub_channel_index != 0;944 return c->offermsg.offer.sub_channel_index != 0;
966}945}
967 946
968static inline void set_channel_affinity_state(struct vmbus_channel *c,
969 enum hv_numa_policy policy)
970{
971 c->affinity_policy = policy;
972}
973
974static inline void set_channel_read_mode(struct vmbus_channel *c,947static inline void set_channel_read_mode(struct vmbus_channel *c,
975 enum hv_callback_mode mode)948 enum hv_callback_mode mode)
976{949{