Skip to content

Commit 49147be

Browse files
committed
x86/xen: allow nesting of same lazy mode
When running as a paravirtualized guest under Xen, Linux is using "lazy mode" for issuing hypercalls which don't need to take immediate effect in order to improve performance (examples are e.g. multiple PTE changes). There are two different lazy modes defined: MMU and CPU lazy mode. Today it is not possible to nest multiple lazy mode sections, even if they are of the same kind. A recent change in memory management added nesting of MMU lazy mode sections, resulting in a regression when running as Xen PV guest. Technically there is no reason why nesting of multiple sections of the same kind of lazy mode shouldn't be allowed. So add support for that for fixing the regression. Fixes: bcc6cc8 ("mm: add default definition of set_ptes()") Signed-off-by: Juergen Gross <[email protected]> Reviewed-by: Boris Ostrovsky <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Juergen Gross <[email protected]>
1 parent a4a7644 commit 49147be

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

arch/x86/include/asm/xen/hypervisor.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,18 @@ enum xen_lazy_mode {
7272
};
7373

7474
DECLARE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode);
75+
DECLARE_PER_CPU(unsigned int, xen_lazy_nesting);
7576

7677
static inline void enter_lazy(enum xen_lazy_mode mode)
7778
{
78-
BUG_ON(this_cpu_read(xen_lazy_mode) != XEN_LAZY_NONE);
79+
enum xen_lazy_mode old_mode = this_cpu_read(xen_lazy_mode);
80+
81+
if (mode == old_mode) {
82+
this_cpu_inc(xen_lazy_nesting);
83+
return;
84+
}
85+
86+
BUG_ON(old_mode != XEN_LAZY_NONE);
7987

8088
this_cpu_write(xen_lazy_mode, mode);
8189
}
@@ -84,7 +92,10 @@ static inline void leave_lazy(enum xen_lazy_mode mode)
8492
{
8593
BUG_ON(this_cpu_read(xen_lazy_mode) != mode);
8694

87-
this_cpu_write(xen_lazy_mode, XEN_LAZY_NONE);
95+
if (this_cpu_read(xen_lazy_nesting) == 0)
96+
this_cpu_write(xen_lazy_mode, XEN_LAZY_NONE);
97+
else
98+
this_cpu_dec(xen_lazy_nesting);
8899
}
89100

90101
enum xen_lazy_mode xen_get_lazy_mode(void);

arch/x86/xen/enlighten_pv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ struct tls_descs {
102102
};
103103

104104
DEFINE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode) = XEN_LAZY_NONE;
105+
DEFINE_PER_CPU(unsigned int, xen_lazy_nesting);
105106

106107
enum xen_lazy_mode xen_get_lazy_mode(void)
107108
{

0 commit comments

Comments
 (0)