On Wed, 25 Apr 2018, kys@xxxxxxxxxxxxxxxxx wrote: > > +struct ipi_arg_ex { > + u32 vector; > + u32 reserved; > + struct hv_vpset vp_set; Please align that in tabular fashion for easy of reading u32 vector; u32 reserved; struct hv_vpset vp_set; > +}; > + > static struct apic orig_apic; > > static u64 hv_apic_icr_read(void) > @@ -97,6 +103,40 @@ static void hv_apic_eoi_write(u32 reg, u32 val) > * IPI implementation on Hyper-V. > */ > > +static int __send_ipi_mask_ex(const struct cpumask *mask, int vector) > +{ > + int nr_bank = 0; > + struct ipi_arg_ex **arg; > + struct ipi_arg_ex *ipi_arg; > + int ret = 1; > + unsigned long flags; This is really horrible to read. struct ipi_arg_ex *ipi_arg; struct ipi_arg_ex **arg; unsigned long flags; bool ret = false; int nr_bank = 0; is really more conveniant for quick reading. So the other more limited function has a lot more sanity checks vs. vector number and other things. Why are they not required here? Comment please. > + local_irq_save(flags); > + arg = (struct ipi_arg_ex **)this_cpu_ptr(hyperv_pcpu_input_arg); > + > + ipi_arg = *arg; > + if (unlikely(!ipi_arg)) > + goto ipi_mask_ex_done; > + > + ipi_arg->vector = vector; > + ipi_arg->reserved = 0; > + ipi_arg->vp_set.valid_bank_mask = 0; > + > + if (!cpumask_equal(mask, cpu_present_mask)) { > + ipi_arg->vp_set.format = HV_GENERIC_SET_SPARCE_4K; > + nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask); nr_bank really confused me. bank_nr is what you mean, not number of banks, right? > + } > + if (!nr_bank) > + ipi_arg->vp_set.format = HV_GENERIC_SET_ALL; > + > + ret = hv_do_rep_hypercall(HVCALL_SEND_IPI_EX, 0, nr_bank, > + ipi_arg, NULL); > + > +ipi_mask_ex_done: > + local_irq_restore(flags); > + return ret; > +} Thanks, tglx _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel