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.
Unified · Split
| @@ -433,14 +433,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel) · 432 unmodified lines | ||
| 433 | 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 | 437 | * Upon suspend, an in-use hv_sock channel is marked as "rescinded" and |
| 446 | 438 | * 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 | 655 | * Starting with Win8, we can statically distribute the incoming |
| 664 | 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 | 658 | * For pre-win8 hosts or non-performance critical channels we assign the |
| 669 | 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 | */ |
| 671 | 665 | static void init_vp_index(struct vmbus_channel *channel, u16 dev_type) |
| 672 | 666 | { |
| 673 | − u32 cur_cpu; | |
| 674 | 667 | bool perf_chn = vmbus_devs[dev_type].perf_device; |
| 675 | − struct vmbus_channel *primary = channel->primary_channel; | |
| 676 | − int next_node; | |
| 677 | 668 | cpumask_var_t available_mask; |
| 678 | 669 | struct cpumask *alloced_mask; |
| 670 | + u32 target_cpu; | |
| 671 | + int numa_node; | |
| 679 | 672 | |
| 680 | 673 | if ((vmbus_proto_version == VERSION_WS2008) || |
| 681 | 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 | 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 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. | |
| 701 | 692 | */ |
| 693 | + spin_lock(&bind_channel_to_cpu_lock); | |
| 702 | 694 | |
| 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; | |
| 713 | 700 | } |
| 714 | − channel->numa_node = next_node; | |
| 715 | − primary = channel; | |
| 701 | + if (cpumask_empty(cpumask_of_node(numa_node))) | |
| 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 | 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 | 711 | * We have cycled through all the CPUs in the node; |
| 723 | 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 | 714 | cpumask_clear(alloced_mask); |
| 726 | 715 | } |
| 727 | 716 | |
| 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)); | |
| 730 | 718 | |
| 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); | |
| 776 | 721 | |
| 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); | |
| 779 | 724 | |
| 780 | 725 | spin_unlock(&bind_channel_to_cpu_lock); |
| 781 | 726 | |
| @@ -689,11 +689,6 @@ union hv_connection_id { · 688 unmodified lines | ||
| 689 | 689 | } u; |
| 690 | 690 | }; |
| 691 | 691 | |
| 692 | −enum hv_numa_policy { | |
| 693 | − HV_BALANCED = 0, | |
| 694 | − HV_LOCALIZED, | |
| 695 | −}; | |
| 696 | − | |
| 697 | 692 | enum vmbus_device_type { |
| 698 | 693 | HV_IDE = 0, |
| 699 | 694 | HV_SCSI, |
| @@ -808,10 +803,6 @@ struct vmbus_channel { · 108 unmodified lines | ||
| 808 | 803 | u32 target_vp; |
| 809 | 804 | /* The corresponding CPUID in the guest */ |
| 810 | 805 | u32 target_cpu; |
| 811 | − /* | |
| 812 | − * State to manage the CPU affiliation of channels. | |
| 813 | − */ | |
| 814 | − struct cpumask alloced_cpus_in_node; | |
| 815 | 806 | int numa_node; |
| 816 | 807 | /* |
| 817 | 808 | * Support for sub-channels. For high performance devices, |
| @@ -898,18 +889,6 @@ struct vmbus_channel { · 80 unmodified lines | ||
| 898 | 889 | */ |
| 899 | 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 | 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 | 944 | return c->offermsg.offer.sub_channel_index != 0; |
| 966 | 945 | } |
| 967 | 946 | |
| 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 | − | |
| 974 | 947 | static inline void set_channel_read_mode(struct vmbus_channel *c, |
| 975 | 948 | enum hv_callback_mode mode) |
| 976 | 949 | { |