Message ID | 20210406111115.8953-3-osalvador@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v6,1/8] drivers/base/memory: Introduce memory_block_{online,offline} | expand |
On 06.04.21 13:11, Oscar Salvador wrote: > When using self-hosted vmemmap pages, the number of pages passed to > {online,offline}_pages might not fully span sections, but they always > fully span pageblocks. > Relax the check account for that case. > > Signed-off-by: Oscar Salvador <osalvador@suse.de> > --- > mm/memory_hotplug.c | 16 ++++++++++++---- > 1 file changed, 12 insertions(+), 4 deletions(-) > > diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c > index 0cdbbfbc5757..5fe3e3942b19 100644 > --- a/mm/memory_hotplug.c > +++ b/mm/memory_hotplug.c > @@ -838,9 +838,13 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, > int ret; > struct memory_notify arg; > > - /* We can only online full sections (e.g., SECTION_IS_ONLINE) */ > + /* We can only offline full sections (e.g., SECTION_IS_ONLINE). > + * However, when using e.g: memmap_on_memory, some pages are initialized > + * prior to calling in here. The remaining amount of pages must be > + * pageblock aligned. > + */ > if (WARN_ON_ONCE(!nr_pages || > - !IS_ALIGNED(pfn | nr_pages, PAGES_PER_SECTION))) > + !IS_ALIGNED(pfn | nr_pages, pageblock_nr_pages))) > return -EINVAL; > > mem_hotplug_begin(); > @@ -1573,9 +1577,13 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages) > int ret, node; > char *reason; > > - /* We can only offline full sections (e.g., SECTION_IS_ONLINE) */ > + /* We can only offline full sections (e.g., SECTION_IS_ONLINE). > + * However, when using e.g: memmap_on_memory, some pages are initialized > + * prior to calling in here. The remaining amount of pages must be > + * pageblock aligned. > + */ > if (WARN_ON_ONCE(!nr_pages || > - !IS_ALIGNED(start_pfn | nr_pages, PAGES_PER_SECTION))) > + !IS_ALIGNED(start_pfn | nr_pages, pageblock_nr_pages))) > return -EINVAL; > > mem_hotplug_begin(); > I'd only relax start_pfn. That way the function is pretty much impossible to abuse for sub-section onlining/offlining. if (WARN_ON_ONCE(!nr_pages || !IS_ALIGNED(start_pfn, pageblock_nr_pages)) !IS_ALIGNED(start_pfn + nr_pages, PAGES_PER_SECTION)))
On 2021-04-06 17:32, David Hildenbrand wrote: > I'd only relax start_pfn. That way the function is pretty much > impossible to abuse for sub-section onlining/offlining. > > if (WARN_ON_ONCE(!nr_pages || > !IS_ALIGNED(start_pfn, pageblock_nr_pages)) > !IS_ALIGNED(start_pfn + nr_pages, PAGES_PER_SECTION))) But this is not going to work. When using memmap_on_memory, the nr of pages that online_pages() and offline_pages() get might be less than PAGES_PER_SECTION, so this check will always blow us up.
> Am 06.04.2021 um 18:34 schrieb Oscar Salvador <osalvador@suse.de>: > > On 2021-04-06 17:32, David Hildenbrand wrote: >> I'd only relax start_pfn. That way the function is pretty much >> impossible to abuse for sub-section onlining/offlining. >> if (WARN_ON_ONCE(!nr_pages || >> !IS_ALIGNED(start_pfn, pageblock_nr_pages)) >> !IS_ALIGNED(start_pfn + nr_pages, PAGES_PER_SECTION))) > > But this is not going to work. > When using memmap_on_memory, the nr of pages that online_pages() and offline_pages() get might be less than PAGES_PER_SECTION, so this check will always blow us up. But not end_pfn as given in my version or what am I missing? > -- > Oscar Salvador > SUSE L3 >
On Tue, Apr 06, 2021 at 10:43:01PM +0200, David Hildenbrand wrote:
> But not end_pfn as given in my version or what am I missing?
Nah, was my fault, I managed to see:
if (WARN_ON_ONCE(!nr_pages ||
!IS_ALIGNED(start_pfn, pageblock_nr_pages))
!IS_ALIGNED(start_pfn | nr_pages, PAGES_PER_SECTION)))
which would not work.
I agree that keeping the PAGES_PER_SECTION check maks this safer, so this all
should have been:
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 0cdbbfbc5757..25e59d5dc13c 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -838,9 +838,14 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages,
int ret;
struct memory_notify arg;
- /* We can only online full sections (e.g., SECTION_IS_ONLINE) */
+ /* We can only offline full sections (e.g., SECTION_IS_ONLINE).
+ * However, when using e.g: memmap_on_memory, some pages are initialized
+ * prior to calling in here. The remaining amount of pages must be
+ * pageblock aligned.
+ */
if (WARN_ON_ONCE(!nr_pages ||
- !IS_ALIGNED(pfn | nr_pages, PAGES_PER_SECTION)))
+ !IS_ALIGNED(pfn, pageblock_nr_pages) ||
+ !IS_ALIGNED(pfn + nr_pages, PAGES_PER_SECTION)))
return -EINVAL;
mem_hotplug_begin();
@@ -1573,9 +1578,14 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages)
int ret, node;
char *reason;
- /* We can only offline full sections (e.g., SECTION_IS_ONLINE) */
+ /* We can only offline full sections (e.g., SECTION_IS_ONLINE).
+ * However, when using e.g: memmap_on_memory, some pages are initialized
+ * prior to calling in here. The remaining amount of pages must be
+ * pageblock aligned.
+ */
if (WARN_ON_ONCE(!nr_pages ||
- !IS_ALIGNED(start_pfn | nr_pages, PAGES_PER_SECTION)))
+ !IS_ALIGNED(start_pfn, pageblock_nr_pages) ||
+ !IS_ALIGNED(start_pfn + nr_pages, PAGES_PER_SECTION)))
return -EINVAL;
mem_hotplug_begin();
On 07.04.21 09:42, Oscar Salvador wrote: > On Tue, Apr 06, 2021 at 10:43:01PM +0200, David Hildenbrand wrote: >> But not end_pfn as given in my version or what am I missing? > > Nah, was my fault, I managed to see: > > if (WARN_ON_ONCE(!nr_pages || > !IS_ALIGNED(start_pfn, pageblock_nr_pages)) > !IS_ALIGNED(start_pfn | nr_pages, PAGES_PER_SECTION))) > > which would not work. > > I agree that keeping the PAGES_PER_SECTION check maks this safer, so this all > should have been: > > diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c > index 0cdbbfbc5757..25e59d5dc13c 100644 > --- a/mm/memory_hotplug.c > +++ b/mm/memory_hotplug.c > @@ -838,9 +838,14 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, > int ret; > struct memory_notify arg; > > - /* We can only online full sections (e.g., SECTION_IS_ONLINE) */ > + /* We can only offline full sections (e.g., SECTION_IS_ONLINE). > + * However, when using e.g: memmap_on_memory, some pages are initialized > + * prior to calling in here. The remaining amount of pages must be > + * pageblock aligned. > + */ > if (WARN_ON_ONCE(!nr_pages || > - !IS_ALIGNED(pfn | nr_pages, PAGES_PER_SECTION))) > + !IS_ALIGNED(pfn, pageblock_nr_pages) || > + !IS_ALIGNED(pfn + nr_pages, PAGES_PER_SECTION))) > return -EINVAL; > > mem_hotplug_begin(); > @@ -1573,9 +1578,14 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages) > int ret, node; > char *reason; > > - /* We can only offline full sections (e.g., SECTION_IS_ONLINE) */ > + /* We can only offline full sections (e.g., SECTION_IS_ONLINE). > + * However, when using e.g: memmap_on_memory, some pages are initialized > + * prior to calling in here. The remaining amount of pages must be > + * pageblock aligned. > + */ > if (WARN_ON_ONCE(!nr_pages || > - !IS_ALIGNED(start_pfn | nr_pages, PAGES_PER_SECTION))) > + !IS_ALIGNED(start_pfn, pageblock_nr_pages) || > + !IS_ALIGNED(start_pfn + nr_pages, PAGES_PER_SECTION))) > return -EINVAL; > > mem_hotplug_begin(); > > > Reviewed-by: David Hildenbrand <david@redhat.com>
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 0cdbbfbc5757..5fe3e3942b19 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -838,9 +838,13 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int ret; struct memory_notify arg; - /* We can only online full sections (e.g., SECTION_IS_ONLINE) */ + /* We can only offline full sections (e.g., SECTION_IS_ONLINE). + * However, when using e.g: memmap_on_memory, some pages are initialized + * prior to calling in here. The remaining amount of pages must be + * pageblock aligned. + */ if (WARN_ON_ONCE(!nr_pages || - !IS_ALIGNED(pfn | nr_pages, PAGES_PER_SECTION))) + !IS_ALIGNED(pfn | nr_pages, pageblock_nr_pages))) return -EINVAL; mem_hotplug_begin(); @@ -1573,9 +1577,13 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages) int ret, node; char *reason; - /* We can only offline full sections (e.g., SECTION_IS_ONLINE) */ + /* We can only offline full sections (e.g., SECTION_IS_ONLINE). + * However, when using e.g: memmap_on_memory, some pages are initialized + * prior to calling in here. The remaining amount of pages must be + * pageblock aligned. + */ if (WARN_ON_ONCE(!nr_pages || - !IS_ALIGNED(start_pfn | nr_pages, PAGES_PER_SECTION))) + !IS_ALIGNED(start_pfn | nr_pages, pageblock_nr_pages))) return -EINVAL; mem_hotplug_begin();
When using self-hosted vmemmap pages, the number of pages passed to {online,offline}_pages might not fully span sections, but they always fully span pageblocks. Relax the check account for that case. Signed-off-by: Oscar Salvador <osalvador@suse.de> --- mm/memory_hotplug.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)