Skip to content

Commit 04df7ac

Browse files
NunoDasNevesliuw
authored andcommitted
Drivers: hv: Introduce per-cpu event ring tail
Add a pointer hv_synic_eventring_tail to track the tail pointer for the SynIC event ring buffer for each SINT. This will be used by the mshv driver, but must be tracked independently since the driver module could be removed and re-inserted. Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com> Reviewed-by: Wei Liu <wei.liu@kernel.org> Reviewed-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com> Link: https://lore.kernel.org/r/1741980536-3865-8-git-send-email-nunodasneves@linux.microsoft.com Signed-off-by: Wei Liu <wei.liu@kernel.org> Message-ID: <1741980536-3865-8-git-send-email-nunodasneves@linux.microsoft.com>
1 parent 21050f6 commit 04df7ac

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

drivers/hv/hv_common.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ static void hv_kmsg_dump_unregister(void);
6868

6969
static struct ctl_table_header *hv_ctl_table_hdr;
7070

71+
/*
72+
* Per-cpu array holding the tail pointer for the SynIC event ring buffer
73+
* for each SINT.
74+
*
75+
* We cannot maintain this in mshv driver because the tail pointer should
76+
* persist even if the mshv driver is unloaded.
77+
*/
78+
u8 * __percpu *hv_synic_eventring_tail;
79+
EXPORT_SYMBOL_GPL(hv_synic_eventring_tail);
80+
7181
/*
7282
* Hyper-V specific initialization and shutdown code that is
7383
* common across all architectures. Called from architecture
@@ -90,6 +100,9 @@ void __init hv_common_free(void)
90100

91101
free_percpu(hyperv_pcpu_input_arg);
92102
hyperv_pcpu_input_arg = NULL;
103+
104+
free_percpu(hv_synic_eventring_tail);
105+
hv_synic_eventring_tail = NULL;
93106
}
94107

95108
/*
@@ -372,6 +385,11 @@ int __init hv_common_init(void)
372385
BUG_ON(!hyperv_pcpu_output_arg);
373386
}
374387

388+
if (hv_root_partition()) {
389+
hv_synic_eventring_tail = alloc_percpu(u8 *);
390+
BUG_ON(!hv_synic_eventring_tail);
391+
}
392+
375393
hv_vp_index = kmalloc_array(nr_cpu_ids, sizeof(*hv_vp_index),
376394
GFP_KERNEL);
377395
if (!hv_vp_index) {
@@ -460,20 +478,21 @@ void __init ms_hyperv_late_init(void)
460478
int hv_common_cpu_init(unsigned int cpu)
461479
{
462480
void **inputarg, **outputarg;
481+
u8 **synic_eventring_tail;
463482
u64 msr_vp_index;
464483
gfp_t flags;
465484
const int pgcount = hv_output_page_exists() ? 2 : 1;
466485
void *mem;
467-
int ret;
486+
int ret = 0;
468487

469488
/* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
470489
flags = irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL;
471490

472491
inputarg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
473492

474493
/*
475-
* hyperv_pcpu_input_arg and hyperv_pcpu_output_arg memory is already
476-
* allocated if this CPU was previously online and then taken offline
494+
* The per-cpu memory is already allocated if this CPU was previously
495+
* online and then taken offline
477496
*/
478497
if (!*inputarg) {
479498
mem = kmalloc(pgcount * HV_HYP_PAGE_SIZE, flags);
@@ -520,11 +539,21 @@ int hv_common_cpu_init(unsigned int cpu)
520539
if (msr_vp_index > hv_max_vp_index)
521540
hv_max_vp_index = msr_vp_index;
522541

523-
return 0;
542+
if (hv_root_partition()) {
543+
synic_eventring_tail = (u8 **)this_cpu_ptr(hv_synic_eventring_tail);
544+
*synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT,
545+
sizeof(u8), flags);
546+
/* No need to unwind any of the above on failure here */
547+
if (unlikely(!*synic_eventring_tail))
548+
ret = -ENOMEM;
549+
}
550+
551+
return ret;
524552
}
525553

526554
int hv_common_cpu_die(unsigned int cpu)
527555
{
556+
u8 **synic_eventring_tail;
528557
/*
529558
* The hyperv_pcpu_input_arg and hyperv_pcpu_output_arg memory
530559
* is not freed when the CPU goes offline as the hyperv_pcpu_input_arg
@@ -537,6 +566,10 @@ int hv_common_cpu_die(unsigned int cpu)
537566
* originally allocated memory is reused in hv_common_cpu_init().
538567
*/
539568

569+
synic_eventring_tail = this_cpu_ptr(hv_synic_eventring_tail);
570+
kfree(*synic_eventring_tail);
571+
*synic_eventring_tail = NULL;
572+
540573
return 0;
541574
}
542575

0 commit comments

Comments
 (0)