@@ -99,7 +99,8 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
99
99
/*
100
100
* IPI implementation on Hyper-V.
101
101
*/
102
- static bool __send_ipi_mask_ex (const struct cpumask * mask , int vector )
102
+ static bool __send_ipi_mask_ex (const struct cpumask * mask , int vector ,
103
+ bool exclude_self )
103
104
{
104
105
struct hv_send_ipi_ex * * arg ;
105
106
struct hv_send_ipi_ex * ipi_arg ;
@@ -123,7 +124,10 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
123
124
124
125
if (!cpumask_equal (mask , cpu_present_mask )) {
125
126
ipi_arg -> vp_set .format = HV_GENERIC_SET_SPARSE_4K ;
126
- nr_bank = cpumask_to_vpset (& (ipi_arg -> vp_set ), mask );
127
+ if (exclude_self )
128
+ nr_bank = cpumask_to_vpset_noself (& (ipi_arg -> vp_set ), mask );
129
+ else
130
+ nr_bank = cpumask_to_vpset (& (ipi_arg -> vp_set ), mask );
127
131
}
128
132
if (nr_bank < 0 )
129
133
goto ipi_mask_ex_done ;
@@ -138,15 +142,25 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
138
142
return hv_result_success (status );
139
143
}
140
144
141
- static bool __send_ipi_mask (const struct cpumask * mask , int vector )
145
+ static bool __send_ipi_mask (const struct cpumask * mask , int vector ,
146
+ bool exclude_self )
142
147
{
143
- int cur_cpu , vcpu ;
148
+ int cur_cpu , vcpu , this_cpu = smp_processor_id () ;
144
149
struct hv_send_ipi ipi_arg ;
145
150
u64 status ;
151
+ unsigned int weight ;
146
152
147
153
trace_hyperv_send_ipi_mask (mask , vector );
148
154
149
- if (cpumask_empty (mask ))
155
+ weight = cpumask_weight (mask );
156
+
157
+ /*
158
+ * Do nothing if
159
+ * 1. the mask is empty
160
+ * 2. the mask only contains self when exclude_self is true
161
+ */
162
+ if (weight == 0 ||
163
+ (exclude_self && weight == 1 && cpumask_test_cpu (this_cpu , mask )))
150
164
return true;
151
165
152
166
if (!hv_hypercall_pg )
@@ -172,6 +186,8 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector)
172
186
ipi_arg .cpu_mask = 0 ;
173
187
174
188
for_each_cpu (cur_cpu , mask ) {
189
+ if (exclude_self && cur_cpu == this_cpu )
190
+ continue ;
175
191
vcpu = hv_cpu_number_to_vp_number (cur_cpu );
176
192
if (vcpu == VP_INVAL )
177
193
return false;
@@ -191,7 +207,7 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector)
191
207
return hv_result_success (status );
192
208
193
209
do_ex_hypercall :
194
- return __send_ipi_mask_ex (mask , vector );
210
+ return __send_ipi_mask_ex (mask , vector , exclude_self );
195
211
}
196
212
197
213
static bool __send_ipi_one (int cpu , int vector )
@@ -208,7 +224,7 @@ static bool __send_ipi_one(int cpu, int vector)
208
224
return false;
209
225
210
226
if (vp >= 64 )
211
- return __send_ipi_mask_ex (cpumask_of (cpu ), vector );
227
+ return __send_ipi_mask_ex (cpumask_of (cpu ), vector , false );
212
228
213
229
status = hv_do_fast_hypercall16 (HVCALL_SEND_IPI , vector , BIT_ULL (vp ));
214
230
return hv_result_success (status );
@@ -222,20 +238,13 @@ static void hv_send_ipi(int cpu, int vector)
222
238
223
239
static void hv_send_ipi_mask (const struct cpumask * mask , int vector )
224
240
{
225
- if (!__send_ipi_mask (mask , vector ))
241
+ if (!__send_ipi_mask (mask , vector , false ))
226
242
orig_apic .send_IPI_mask (mask , vector );
227
243
}
228
244
229
245
static void hv_send_ipi_mask_allbutself (const struct cpumask * mask , int vector )
230
246
{
231
- unsigned int this_cpu = smp_processor_id ();
232
- struct cpumask new_mask ;
233
- const struct cpumask * local_mask ;
234
-
235
- cpumask_copy (& new_mask , mask );
236
- cpumask_clear_cpu (this_cpu , & new_mask );
237
- local_mask = & new_mask ;
238
- if (!__send_ipi_mask (local_mask , vector ))
247
+ if (!__send_ipi_mask (mask , vector , true))
239
248
orig_apic .send_IPI_mask_allbutself (mask , vector );
240
249
}
241
250
@@ -246,7 +255,7 @@ static void hv_send_ipi_allbutself(int vector)
246
255
247
256
static void hv_send_ipi_all (int vector )
248
257
{
249
- if (!__send_ipi_mask (cpu_online_mask , vector ))
258
+ if (!__send_ipi_mask (cpu_online_mask , vector , false ))
250
259
orig_apic .send_IPI_all (vector );
251
260
}
252
261
0 commit comments