]>
Commit | Line | Data |
---|---|---|
25085850 GKH |
1 | From foo@baz Tue 04 Jun 2019 04:44:10 PM CEST |
2 | From: Linus Torvalds <torvalds@linux-foundation.org> | |
3 | Date: Thu, 11 Apr 2019 10:06:20 -0700 | |
4 | Subject: mm: make page ref count overflow check tighter and more explicit | |
5 | ||
6 | From: Linus Torvalds <torvalds@linux-foundation.org> | |
7 | ||
8 | commit f958d7b528b1b40c44cfda5eabe2d82760d868c3 upstream. | |
9 | ||
10 | We have a VM_BUG_ON() to check that the page reference count doesn't | |
11 | underflow (or get close to overflow) by checking the sign of the count. | |
12 | ||
13 | That's all fine, but we actually want to allow people to use a "get page | |
14 | ref unless it's already very high" helper function, and we want that one | |
15 | to use the sign of the page ref (without triggering this VM_BUG_ON). | |
16 | ||
17 | Change the VM_BUG_ON to only check for small underflows (or _very_ close | |
18 | to overflowing), and ignore overflows which have strayed into negative | |
19 | territory. | |
20 | ||
21 | Acked-by: Matthew Wilcox <willy@infradead.org> | |
22 | Cc: Jann Horn <jannh@google.com> | |
23 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
24 | Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> | |
25 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
26 | --- | |
27 | include/linux/mm.h | 6 +++++- | |
28 | 1 file changed, 5 insertions(+), 1 deletion(-) | |
29 | ||
30 | --- a/include/linux/mm.h | |
31 | +++ b/include/linux/mm.h | |
32 | @@ -763,6 +763,10 @@ static inline bool is_zone_device_page(c | |
33 | } | |
34 | #endif | |
35 | ||
36 | +/* 127: arbitrary random number, small enough to assemble well */ | |
37 | +#define page_ref_zero_or_close_to_overflow(page) \ | |
38 | + ((unsigned int) page_ref_count(page) + 127u <= 127u) | |
39 | + | |
40 | static inline void get_page(struct page *page) | |
41 | { | |
42 | page = compound_head(page); | |
43 | @@ -770,7 +774,7 @@ static inline void get_page(struct page | |
44 | * Getting a normal page or the head of a compound page | |
45 | * requires to already have an elevated page->_refcount. | |
46 | */ | |
47 | - VM_BUG_ON_PAGE(page_ref_count(page) <= 0, page); | |
48 | + VM_BUG_ON_PAGE(page_ref_zero_or_close_to_overflow(page), page); | |
49 | page_ref_inc(page); | |
50 | ||
51 | if (unlikely(is_zone_device_page(page))) |