@@ -99,6 +99,9 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
99
99
int nr_bank = 0 ;
100
100
int ret = 1 ;
101
101
102
+ if (!(ms_hyperv .hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED ))
103
+ return false;
104
+
102
105
local_irq_save (flags );
103
106
arg = (struct ipi_arg_ex * * )this_cpu_ptr (hyperv_pcpu_input_arg );
104
107
@@ -140,8 +143,18 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector)
140
143
if ((vector < HV_IPI_LOW_VECTOR ) || (vector > HV_IPI_HIGH_VECTOR ))
141
144
return false;
142
145
143
- if ((ms_hyperv .hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED ))
144
- return __send_ipi_mask_ex (mask , vector );
146
+ /*
147
+ * From the supplied CPU set we need to figure out if we can get away
148
+ * with cheaper HVCALL_SEND_IPI hypercall. This is possible when the
149
+ * highest VP number in the set is < 64. As VP numbers are usually in
150
+ * ascending order and match Linux CPU ids, here is an optimization:
151
+ * we check the VP number for the highest bit in the supplied set first
152
+ * so we can quickly find out if using HVCALL_SEND_IPI_EX hypercall is
153
+ * a must. We will also check all VP numbers when walking the supplied
154
+ * CPU set to remain correct in all cases.
155
+ */
156
+ if (hv_cpu_number_to_vp_number (cpumask_last (mask )) >= 64 )
157
+ goto do_ex_hypercall ;
145
158
146
159
ipi_arg .vector = vector ;
147
160
ipi_arg .cpu_mask = 0 ;
@@ -153,16 +166,17 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector)
153
166
* only target upto 64 CPUs.
154
167
*/
155
168
if (vcpu >= 64 )
156
- goto ipi_mask_done ;
169
+ goto do_ex_hypercall ;
157
170
158
171
__set_bit (vcpu , (unsigned long * )& ipi_arg .cpu_mask );
159
172
}
160
173
161
174
ret = hv_do_fast_hypercall16 (HVCALL_SEND_IPI , ipi_arg .vector ,
162
175
ipi_arg .cpu_mask );
163
-
164
- ipi_mask_done :
165
176
return ((ret == 0 ) ? true : false);
177
+
178
+ do_ex_hypercall :
179
+ return __send_ipi_mask_ex (mask , vector );
166
180
}
167
181
168
182
static bool __send_ipi_one (int cpu , int vector )
@@ -218,10 +232,7 @@ static void hv_send_ipi_self(int vector)
218
232
void __init hv_apic_init (void )
219
233
{
220
234
if (ms_hyperv .hints & HV_X64_CLUSTER_IPI_RECOMMENDED ) {
221
- if ((ms_hyperv .hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED ))
222
- pr_info ("Hyper-V: Using ext hypercalls for IPI\n" );
223
- else
224
- pr_info ("Hyper-V: Using IPI hypercalls\n" );
235
+ pr_info ("Hyper-V: Using IPI hypercalls\n" );
225
236
/*
226
237
* Set the IPI entry points.
227
238
*/
0 commit comments