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
433433 spin_unlock_irqrestore(&primary_channel->lock, flags);
434434 }
435435
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−
444436 /*
445437 * Upon suspend, an in-use hv_sock channel is marked as "rescinded" and
446438 * 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
662654 /*
663655 * Starting with Win8, we can statically distribute the incoming
664656 * 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.
667657 *
668658 * For pre-win8 hosts or non-performance critical channels we assign the
669659 * 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.
670664 */
671665 static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
672666 {
673− u32 cur_cpu;
674667 bool perf_chn = vmbus_devs[dev_type].perf_device;
675− struct vmbus_channel *primary = channel->primary_channel;
676− int next_node;
677668 cpumask_var_t available_mask;
678669 struct cpumask *alloced_mask;
670+ u32 target_cpu;
671+ int numa_node;
679672
680673 if ((vmbus_proto_version == VERSION_WS2008) ||
681674 (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
693686 return;
694687 }
695688
696− spin_lock(&bind_channel_to_cpu_lock);
697−
698689 /*
699− * Based on the channel affinity policy, we will assign the NUMA
700− * nodes.
690+ * Serializes the accesses to the global variable next_numa_node_id.
691+ * See also the header comment of the spin lock declaration.
701692 */
693+ spin_lock(&bind_channel_to_cpu_lock);
702694
703− if ((channel->affinity_policy == HV_BALANCED) || (!primary)) {
704− while (true) {
705− next_node = next_numa_node_id++;
706− if (next_node == nr_node_ids) {
707− next_node = next_numa_node_id = 0;
708− continue;
709− }
710− if (cpumask_empty(cpumask_of_node(next_node)))
711− continue;
712− break;
695+ while (true) {
696+ numa_node = next_numa_node_id++;
697+ if (numa_node == nr_node_ids) {
698+ next_numa_node_id = 0;
699+ continue;
713700 }
714− channel->numa_node = next_node;
715− primary = channel;
701+ if (cpumask_empty(cpumask_of_node(numa_node)))
702+ continue;
703+ break;
716704 }
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];
718707
719708 if (cpumask_weight(alloced_mask) ==
720− cpumask_weight(cpumask_of_node(primary->numa_node))) {
709+ cpumask_weight(cpumask_of_node(numa_node))) {
721710 /*
722711 * We have cycled through all the CPUs in the node;
723712 * reset the alloced map.
@@ -725,57 +714,13 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type) · 1 unmodified line
725714 cpumask_clear(alloced_mask);
726715 }
727716
728− cpumask_xor(available_mask, alloced_mask,
729− cpumask_of_node(primary->numa_node));
717+ cpumask_xor(available_mask, alloced_mask, cpumask_of_node(numa_node));
730718
731− cur_cpu = -1;
732−
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− }
719+ target_cpu = cpumask_first(available_mask);
720+ cpumask_set_cpu(target_cpu, alloced_mask);
776721
777− channel->target_cpu = cur_cpu;
778− channel->target_vp = hv_cpu_number_to_vp_number(cur_cpu);
722+ channel->target_cpu = target_cpu;
723+ channel->target_vp = hv_cpu_number_to_vp_number(target_cpu);
779724
780725 spin_unlock(&bind_channel_to_cpu_lock);
781726
include/linux/hyperv.h+0−27
@@ -689,11 +689,6 @@ union hv_connection_id { · 688 unmodified lines
689689 } u;
690690 };
691691
692−enum hv_numa_policy {
693− HV_BALANCED = 0,
694− HV_LOCALIZED,
695−};
696−
697692 enum vmbus_device_type {
698693 HV_IDE = 0,
699694 HV_SCSI,
@@ -808,10 +803,6 @@ struct vmbus_channel { · 108 unmodified lines
808803 u32 target_vp;
809804 /* The corresponding CPUID in the guest */
810805 u32 target_cpu;
811− /*
812− * State to manage the CPU affiliation of channels.
813− */
814− struct cpumask alloced_cpus_in_node;
815806 int numa_node;
816807 /*
817808 * Support for sub-channels. For high performance devices,
@@ -898,18 +889,6 @@ struct vmbus_channel { · 80 unmodified lines
898889 */
899890 bool low_latency;
900891
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−
913892 bool probe_done;
914893
915894 /*
@@ -965,12 +944,6 @@ static inline bool is_sub_channel(const struct vmbus_channel *c) · 49 unmodified lines
965944 return c->offermsg.offer.sub_channel_index != 0;
966945 }
967946
968−static inline void set_channel_affinity_state(struct vmbus_channel *c,
969− enum hv_numa_policy policy)
970−{
971− c->affinity_policy = policy;
972−}
973−
974947 static inline void set_channel_read_mode(struct vmbus_channel *c,
975948 enum hv_callback_mode mode)
976949 {