Skip to content

Commit 2cb7c9c

Browse files
David HildenbrandIngo Molnar
authored andcommitted
sched/preempt, mm/kmap: Explicitly disable/enable preemption in kmap_atomic_*
The existing code relies on pagefault_disable() implicitly disabling preemption, so that no schedule will happen between kmap_atomic() and kunmap_atomic(). Let's make this explicit, to prepare for pagefault_disable() not touching preemption anymore. Reviewed-and-tested-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: David.Laight@ACULAB.COM Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: airlied@linux.ie Cc: akpm@linux-foundation.org Cc: benh@kernel.crashing.org Cc: bigeasy@linutronix.de Cc: borntraeger@de.ibm.com Cc: daniel.vetter@intel.com Cc: heiko.carstens@de.ibm.com Cc: herbert@gondor.apana.org.au Cc: hocko@suse.cz Cc: hughd@google.com Cc: mst@redhat.com Cc: paulus@samba.org Cc: ralf@linux-mips.org Cc: schwidefsky@de.ibm.com Cc: yang.shi@windriver.com Link: http://lkml.kernel.org/r/1431359540-32227-5-git-send-email-dahi@linux.vnet.ibm.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent b3c395e commit 2cb7c9c

File tree

15 files changed

+38
-7
lines changed

15 files changed

+38
-7
lines changed

arch/arm/mm/highmem.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ void *kmap_atomic(struct page *page)
5959
void *kmap;
6060
int type;
6161

62+
preempt_disable();
6263
pagefault_disable();
6364
if (!PageHighMem(page))
6465
return page_address(page);
@@ -121,6 +122,7 @@ void __kunmap_atomic(void *kvaddr)
121122
kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
122123
}
123124
pagefault_enable();
125+
preempt_enable();
124126
}
125127
EXPORT_SYMBOL(__kunmap_atomic);
126128

@@ -130,6 +132,7 @@ void *kmap_atomic_pfn(unsigned long pfn)
130132
int idx, type;
131133
struct page *page = pfn_to_page(pfn);
132134

135+
preempt_disable();
133136
pagefault_disable();
134137
if (!PageHighMem(page))
135138
return page_address(page);

arch/frv/mm/highmem.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ void *kmap_atomic(struct page *page)
4242
unsigned long paddr;
4343
int type;
4444

45+
preempt_disable();
4546
pagefault_disable();
4647
type = kmap_atomic_idx_push();
4748
paddr = page_to_phys(page);
@@ -85,5 +86,6 @@ void __kunmap_atomic(void *kvaddr)
8586
}
8687
kmap_atomic_idx_pop();
8788
pagefault_enable();
89+
preempt_enable();
8890
}
8991
EXPORT_SYMBOL(__kunmap_atomic);

arch/metag/mm/highmem.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void *kmap_atomic(struct page *page)
4343
unsigned long vaddr;
4444
int type;
4545

46-
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
46+
preempt_disable();
4747
pagefault_disable();
4848
if (!PageHighMem(page))
4949
return page_address(page);
@@ -82,6 +82,7 @@ void __kunmap_atomic(void *kvaddr)
8282
}
8383

8484
pagefault_enable();
85+
preempt_enable();
8586
}
8687
EXPORT_SYMBOL(__kunmap_atomic);
8788

@@ -95,6 +96,7 @@ void *kmap_atomic_pfn(unsigned long pfn)
9596
unsigned long vaddr;
9697
int type;
9798

99+
preempt_disable();
98100
pagefault_disable();
99101

100102
type = kmap_atomic_idx_push();

arch/microblaze/mm/highmem.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot)
3737
unsigned long vaddr;
3838
int idx, type;
3939

40-
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
40+
preempt_disable();
4141
pagefault_disable();
4242
if (!PageHighMem(page))
4343
return page_address(page);
@@ -63,6 +63,7 @@ void __kunmap_atomic(void *kvaddr)
6363

6464
if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
6565
pagefault_enable();
66+
preempt_enable();
6667
return;
6768
}
6869

@@ -84,5 +85,6 @@ void __kunmap_atomic(void *kvaddr)
8485
#endif
8586
kmap_atomic_idx_pop();
8687
pagefault_enable();
88+
preempt_enable();
8789
}
8890
EXPORT_SYMBOL(__kunmap_atomic);

arch/mips/mm/highmem.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ void *kmap_atomic(struct page *page)
4747
unsigned long vaddr;
4848
int idx, type;
4949

50-
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
50+
preempt_disable();
5151
pagefault_disable();
5252
if (!PageHighMem(page))
5353
return page_address(page);
@@ -72,6 +72,7 @@ void __kunmap_atomic(void *kvaddr)
7272

7373
if (vaddr < FIXADDR_START) { // FIXME
7474
pagefault_enable();
75+
preempt_enable();
7576
return;
7677
}
7778

@@ -92,6 +93,7 @@ void __kunmap_atomic(void *kvaddr)
9293
#endif
9394
kmap_atomic_idx_pop();
9495
pagefault_enable();
96+
preempt_enable();
9597
}
9698
EXPORT_SYMBOL(__kunmap_atomic);
9799

@@ -104,6 +106,7 @@ void *kmap_atomic_pfn(unsigned long pfn)
104106
unsigned long vaddr;
105107
int idx, type;
106108

109+
preempt_disable();
107110
pagefault_disable();
108111

109112
type = kmap_atomic_idx_push();

arch/mn10300/include/asm/highmem.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ static inline void *kmap_atomic(struct page *page)
7575
unsigned long vaddr;
7676
int idx, type;
7777

78+
preempt_disable();
7879
pagefault_disable();
7980
if (page < highmem_start_page)
8081
return page_address(page);
@@ -98,6 +99,7 @@ static inline void __kunmap_atomic(unsigned long vaddr)
9899

99100
if (vaddr < FIXADDR_START) { /* FIXME */
100101
pagefault_enable();
102+
preempt_enable();
101103
return;
102104
}
103105

@@ -122,6 +124,7 @@ static inline void __kunmap_atomic(unsigned long vaddr)
122124

123125
kmap_atomic_idx_pop();
124126
pagefault_enable();
127+
preempt_enable();
125128
}
126129
#endif /* __KERNEL__ */
127130

arch/parisc/include/asm/cacheflush.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ static inline void kunmap(struct page *page)
142142

143143
static inline void *kmap_atomic(struct page *page)
144144
{
145+
preempt_disable();
145146
pagefault_disable();
146147
return page_address(page);
147148
}
@@ -150,6 +151,7 @@ static inline void __kunmap_atomic(void *addr)
150151
{
151152
flush_kernel_dcache_page_addr(addr);
152153
pagefault_enable();
154+
preempt_enable();
153155
}
154156

155157
#define kmap_atomic_prot(page, prot) kmap_atomic(page)

arch/powerpc/mm/highmem.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot)
3434
unsigned long vaddr;
3535
int idx, type;
3636

37-
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
37+
preempt_disable();
3838
pagefault_disable();
3939
if (!PageHighMem(page))
4040
return page_address(page);
@@ -59,6 +59,7 @@ void __kunmap_atomic(void *kvaddr)
5959

6060
if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
6161
pagefault_enable();
62+
preempt_enable();
6263
return;
6364
}
6465

@@ -82,5 +83,6 @@ void __kunmap_atomic(void *kvaddr)
8283

8384
kmap_atomic_idx_pop();
8485
pagefault_enable();
86+
preempt_enable();
8587
}
8688
EXPORT_SYMBOL(__kunmap_atomic);

arch/sparc/mm/highmem.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void *kmap_atomic(struct page *page)
5353
unsigned long vaddr;
5454
long idx, type;
5555

56-
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
56+
preempt_disable();
5757
pagefault_disable();
5858
if (!PageHighMem(page))
5959
return page_address(page);
@@ -91,6 +91,7 @@ void __kunmap_atomic(void *kvaddr)
9191

9292
if (vaddr < FIXADDR_START) { // FIXME
9393
pagefault_enable();
94+
preempt_enable();
9495
return;
9596
}
9697

@@ -126,5 +127,6 @@ void __kunmap_atomic(void *kvaddr)
126127

127128
kmap_atomic_idx_pop();
128129
pagefault_enable();
130+
preempt_enable();
129131
}
130132
EXPORT_SYMBOL(__kunmap_atomic);

arch/tile/mm/highmem.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot)
201201
int idx, type;
202202
pte_t *pte;
203203

204-
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
204+
preempt_disable();
205205
pagefault_disable();
206206

207207
/* Avoid icache flushes by disallowing atomic executable mappings. */
@@ -259,6 +259,7 @@ void __kunmap_atomic(void *kvaddr)
259259
}
260260

261261
pagefault_enable();
262+
preempt_enable();
262263
}
263264
EXPORT_SYMBOL(__kunmap_atomic);
264265

arch/x86/mm/highmem_32.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot)
3535
unsigned long vaddr;
3636
int idx, type;
3737

38-
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
38+
preempt_disable();
3939
pagefault_disable();
4040

4141
if (!PageHighMem(page))
@@ -100,6 +100,7 @@ void __kunmap_atomic(void *kvaddr)
100100
#endif
101101

102102
pagefault_enable();
103+
preempt_enable();
103104
}
104105
EXPORT_SYMBOL(__kunmap_atomic);
105106

arch/x86/mm/iomap_32.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot)
5959
unsigned long vaddr;
6060
int idx, type;
6161

62+
preempt_disable();
6263
pagefault_disable();
6364

6465
type = kmap_atomic_idx_push();
@@ -117,5 +118,6 @@ iounmap_atomic(void __iomem *kvaddr)
117118
}
118119

119120
pagefault_enable();
121+
preempt_enable();
120122
}
121123
EXPORT_SYMBOL_GPL(iounmap_atomic);

arch/xtensa/mm/highmem.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ void *kmap_atomic(struct page *page)
4242
enum fixed_addresses idx;
4343
unsigned long vaddr;
4444

45+
preempt_disable();
4546
pagefault_disable();
4647
if (!PageHighMem(page))
4748
return page_address(page);
@@ -79,6 +80,7 @@ void __kunmap_atomic(void *kvaddr)
7980
}
8081

8182
pagefault_enable();
83+
preempt_enable();
8284
}
8385
EXPORT_SYMBOL(__kunmap_atomic);
8486

include/linux/highmem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ static inline void kunmap(struct page *page)
6565

6666
static inline void *kmap_atomic(struct page *page)
6767
{
68+
preempt_disable();
6869
pagefault_disable();
6970
return page_address(page);
7071
}
@@ -73,6 +74,7 @@ static inline void *kmap_atomic(struct page *page)
7374
static inline void __kunmap_atomic(void *addr)
7475
{
7576
pagefault_enable();
77+
preempt_enable();
7678
}
7779

7880
#define kmap_atomic_pfn(pfn) kmap_atomic(pfn_to_page(pfn))

include/linux/io-mapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ static inline void __iomem *
141141
io_mapping_map_atomic_wc(struct io_mapping *mapping,
142142
unsigned long offset)
143143
{
144+
preempt_disable();
144145
pagefault_disable();
145146
return ((char __force __iomem *) mapping) + offset;
146147
}
@@ -149,6 +150,7 @@ static inline void
149150
io_mapping_unmap_atomic(void __iomem *vaddr)
150151
{
151152
pagefault_enable();
153+
preempt_enable();
152154
}
153155

154156
/* Non-atomic map/unmap */

0 commit comments

Comments
 (0)