Add memrlimit controller (v5)
Subsystems (15)
cover Add memrlimit controller (v5)
This is the fifth version of the address space control patches. These patches are against 2.6.26-rc2-mm1 and have been tested using KVM in SMP mode, both on a powerpc box
The goal of this patch is to implement a virtual address space controller using cgroups. The documentation describes the controller, it's goal and usage in further details.
Reviews, Comments?
Changelog
Patches [1/4] and [2/4] are unchanged
Patch [3/4] and [4/4] now formally use mmap_sem to protect mm->owner races.
Previous version of this patchset can be found at
http://lwn.net/Articles/282237/
Series
memrlimit-controller-add-documentation.patch memrlimit-controller-setup.patch cgroup-add-task-to-mm-owner-callbacks.patch memrlimit-controller-address-space-accounting-and-control.patch
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/4 Add memrlimit controller documentation (v5)
Documentation patch - describes the goals and usage of the memrlimit controller.
---
Documentation/controllers/memrlimit.txt | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
Documentation/controllers/memrlimit.txt new file +29 -0
@@ -0,0 +1,29 @@ +This controller is enabled by the CONFIG_CGROUP_MEMRLIMIT_CTLR option. Prior +to reading this documentation please read Documentation/cgroups.txt and +Documentation/controllers/memory.txt. Several of the principles of this +controller are similar to the memory resource controller. + +This controller framework is designed to be extensible to control any +memory resource limit with little effort. + +This new controller, controls the address space expansion of the tasks +belonging to a cgroup. Address space control is provided along the same lines as +RLIMIT_AS control, which is available via getrlimit(2)/setrlimit(2). +The interface for controlling address space is provided through +"rlimit.limit_in_bytes". The file is similar to "limit_in_bytes" w.r.t. the user +interface. Please see section 3 of the memory resource controller documentation +for more details on how to use the user interface to get and set values. + +The "memrlimit.usage_in_bytes" file provides information about the total address +space usage of the tasks in the cgroup, in bytes. + +Advantages of providing this feature + +1. Control over virtual address space allows for a cgroup to fail gracefully + i.e., via a malloc or mmap failure as compared to OOM kill when no + pages can be reclaimed. +2. It provides better control over how many pages can be swapped out when + the cgroup goes over its limit. A badly setup cgroup can cause excessive + swapping. Providing control over the address space allocations ensures + that the system administrator has control over the total swapping that + can take place.
_
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [-mm][PATCH 1/4] Add memrlimit controller documentation (v5)
Quoted 17 lines · On Wed, 21 May 2008 20:59:37 +0530 Balbir Singh <[email protected]>…
Documentation patch - describes the goals and usage of the memrlimit controller.
Signed-off-by Balbir Singh <[email protected]>---
Documentation/controllers/memrlimit.txt | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)diff -puN
/dev/nullDocumentation/controllers/memrlimit.txtDocumentation/controllers/memrlimit.txt new file +1
-0@@ -0,0 +1,29 @@ +This controller is enabled by the CONFIG_CGROUP_MEMRLIMIT_CTLR option. Prior
Documentation/controllers/memrlimit.txt line 11
Quoted 10 lines
Documentation/controllers/memrlimit.txt new file +10
-0+to reading this documentation please read Documentation/cgroups.txt and +Documentation/controllers/memory.txt. Several of the principles of this +controller are similar to the memory resource controller. + +This controller framework is designed to be extensible to control any +memory resource limit with little effort. + +This new controller, controls the address space expansion of the tasks +belonging to a cgroup. Address space control is provided along the same lines as +RLIMIT_AS control, which is available via getrlimit(2)/setrlimit(2).
Still would like to see more details here. RLIMIT_AS is simple because it applies to a single mm. But a control group may contain multiple mm's, and those mm's can share stuff.
The sharing probably isn't important in this situation, where we're only concerned with virtual address space size, rather than real memory. But still, readers will be wondering about this.
They also will be wondering about the handling of threads versus heavyweight processes. _we_ know that, but users and administrators may not.
Documentation/controllers/memrlimit.txt line 24
Quoted 13 lines
Documentation/controllers/memrlimit.txt new file +13
-0+The interface for controlling address space is provided through +"rlimit.limit_in_bytes". The file is similar to "limit_in_bytes" w.r.t. the user +interface. Please see section 3 of the memory resource controller documentation +for more details on how to use the user interface to get and set values. + +The "memrlimit.usage_in_bytes" file provides information about the total address +space usage of the tasks in the cgroup, in bytes. + +Advantages of providing this feature + +1. Control over virtual address space allows for a cgroup to fail gracefully + i.e., via a malloc or mmap failure as compared to OOM kill when no + pages can be reclaimed.
Well it's more than "i.e.". It would be better to precisely spell out the behaviour of this feature. It's mmap() and brk() only, is it not? malloc() isn't a system call ;)
Ideally, either the changelog, this document or code comments should be sufficient for a manpage to be written. And this level of description will lead to better code review and quite likely a better feature.
Documentation/controllers/memrlimit.txt line 29
Quoted 5 lines
Documentation/controllers/memrlimit.txt new file +5
-0+2. It provides better control over how many pages can be swapped out when + the cgroup goes over its limit. A badly setup cgroup can cause excessive + swapping. Providing control over the address space allocations ensures + that the system administrator has control over the total swapping that + can take place.
IOW: what, exactly and completely, does this feature do?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 1/4] Add memrlimit controller documentation (v5)
Quoted 51 lines · Andrew Morton
Quoted 16 lines · On Wed, 21 May 2008 20:59:37 +0530 Balbir Singh <[email protected]>…
Documentation patch - describes the goals and usage of the memrlimit controller.
Signed-off-by Balbir Singh <[email protected]>---
Documentation/controllers/memrlimit.txt | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)diff -puN
/dev/nullDocumentation/controllers/memrlimit.txtDocumentation/controllers/memrlimit.txt new file +1
-0@@ -0,0 +1,29 @@ +This controller is enabled by the CONFIG_CGROUP_MEMRLIMIT_CTLR option. PriorDocumentation/controllers/memrlimit.txt line 11
Quoted 10 lines
Documentation/controllers/memrlimit.txt new file +10
-0+to reading this documentation please read Documentation/cgroups.txt and +Documentation/controllers/memory.txt. Several of the principles of this +controller are similar to the memory resource controller. + +This controller framework is designed to be extensible to control any +memory resource limit with little effort. + +This new controller, controls the address space expansion of the tasks +belonging to a cgroup. Address space control is provided along the same lines as +RLIMIT_AS control, which is available via getrlimit(2)/setrlimit(2).Still would like to see more details here.
RLIMIT_ASis simple because it applies to a single mm. But a control group may contain multiple mm's, and those mm's can share stuff.The sharing probably isn't important in this situation, where we're only concerned with virtual address space size, rather than real memory. But still, readers will be wondering about this.
They also will be wondering about the handling of threads versus heavyweight processes. _we_ know that, but users and administrators may not.
Quoted 9 lines
Documentation/controllers/memrlimit.txt new file +9
-0+The interface for controlling address space is provided through +"rlimit.limit_in_bytes". The file is similar to "limit_in_bytes" w.r.t. the user +interface. Please see section 3 of the memory resource controller documentation +for more details on how to use the user interface to get and set values. + +The "memrlimit.usage_in_bytes" file provides information about the total address +space usage of the tasks in the cgroup, in bytes. + +Advantages of providing this feature
Quoted 9 lines
Documentation/controllers/memrlimit.txt line 24
Quoted 4 lines
Documentation/controllers/memrlimit.txt new file +4
-0+ +1. Control over virtual address space allows for a cgroup to fail gracefully + i.e., via a malloc or mmap failure as compared to OOM kill when no + pages can be reclaimed.Well it's more than "i.e.". It would be better to precisely spell out the behaviour of this feature. It's
mmap()andbrk()only, is it not?malloc()isn't a system call ;)
Yes, true. I thought about wording it that way, but end users understand mmap() and malloc() better that mmap with MAP_ANONYMOUS or brk(), sbrk().
Quoted 4 lines
Ideally, either the changelog, this document or code comments should be sufficient for a manpage to be written. And this level of description will lead to better code review and quite likely a better feature.
That makes a lot of sense. I'll work on enhancing this documentation.
Quoted 7 lines
Documentation/controllers/memrlimit.txt line 29
Quoted 5 lines
Documentation/controllers/memrlimit.txt new file +5
-0+2. It provides better control over how many pages can be swapped out when + the cgroup goes over its limit. A badly setup cgroup can cause excessive + swapping. Providing control over the address space allocations ensures + that the system administrator has control over the total swapping that + can take place.IOW: what, exactly and completely, does this feature do?
I'll send an update with more details with an example if possible.
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 2/4 Setup the memrlimit controller (v5)
In reply to Balbir SinghThis patch sets up the rlimit cgroup controller. It adds the basic create, destroy and populate functionality. The user interface provided is very similar to the memory resource controller. The rlimit controller can be enhanced easily in the future to control mlocked pages.
Changelog v3->v4
1. Use PAGE_ALIGN()
2. Rename rlimit to memrlimit
---
include/linux/cgroup_subsys.h | 4 + include/linux/memrlimitcgroup.h | 19 +++++ init/Kconfig | 10 ++ mm/Makefile | 1 mm/memrlimitcgroup.c | 144 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 178 insertions(+)
include/linux/cgroup_subsys.h renamed from include/linux/cgroup_subsys.h~memrlimit-controller-setup +4 -0
@@ -47,4 +47,8 @@ SUBSYS(mem_cgroup) SUBSYS(devices)#endif +#ifdef CONFIG_CGROUP_MEMRLIMIT_CTLR +SUBSYS(memrlimit_cgroup) +#endif +/* */
include/linux/memrlimitcgroup.h new file +19 -0
@@ -0,0 +1,19 @@ +/* +* Copyright A(C) International Business Machines Corp., 2008 +* +* Author: Balbir Singh <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ +#ifndef LINUX_MEMRLIMITCGROUP_H +#define LINUX_MEMRLIMITCGROUP_H + +#endif /* LINUX_MEMRLIMITCGROUP_H */
init/Kconfig renamed from init/Kconfig~memrlimit-controller-setup +10 -0
@@ -407,6 +407,16 @@ config CGROUP_MEM_RES_CTLR This config option also selects MM_OWNER config option, which could in turn add some fork/exit overhead. +config CGROUP_MEMRLIMIT_CTLR + bool "Memory resource limit controls for cgroups" + depends on CGROUPS && RESOURCE_COUNTERS && MMU + select MM_OWNER + help + Provides resource limits for all the tasks belonging to a + control group. CGROUP_MEM_RES_CTLR provides support for physical + memory RSS and Page Cache control. Virtual address space control + is provided by this controller. + config SYSFS_DEPRECATED bool
mm/Makefile renamed from mm/Makefile~memrlimit-controller-setup +1 -0
@@ -34,4 +34,5 @@ obj-$(CONFIG_MIGRATION) += migrate.o obj-$(CONFIG_SMP) += allocpercpu.o obj-$(CONFIG_QUICKLIST) += quicklist.o obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o +obj-$(CONFIG_CGROUP_MEMRLIMIT_CTLR) += memrlimitcgroup.o
mm/memrlimitcgroup.c new file +144 -0
144 lines not on this page · raw message
_
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 1 line · On Wed, 21 May 2008 20:59:48 +0530 Balbir Singh <[email protected]>…
+static int
memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp)
grumble. I think I requested a checkpatch warning whenever it comes across "tmp" or "temp". Even better would be a gcc coredump.
I'm sure there's something more meaningful we could use here?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 7 lines · Andrew Morton
Quoted 1 line · On Wed, 21 May 2008 20:59:48 +0530 Balbir Singh <[email protected]>…
+static int
memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp)grumble. I think I requested a checkpatch warning whenever it comes across "tmp" or "temp". Even better would be a gcc coredump.
:-)
Quoted 1 line
I'm sure there's something more meaningful we could use here?
I'll send a patch to fix this.
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
In reply to Balbir SinghReview
Quoted 9 lines · Balbir Singh
(quoted diff) +9
-0+static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp) +{ + *tmp = memparse(buf, &buf); + if (*buf != '\0') + return -EINVAL; + + *tmp = PAGE_ALIGN(*tmp); + return 0; +}
We shouldn't use PAGE_ALIGN() here, otherwise we limit the address space to 4GB on 32-bit architectures (that could be reasonable, because this is a per-cgroup limit and not per-process).
---mm/memrlimitcgroup.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
mm/memrlimitcgroup.c +0 -0
@@ -29,6 +29,8 @@
#include <linux/res_counter.h>
#include <linux/memrlimitcgroup.h>
+#define PAGE_ALIGN64(addr) (((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT) +
struct cgroup_subsys memrlimit_cgroup_subsys;
struct memrlimit_cgroup {
@@ -124,7 +126,7 @@ static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp)
if (*buf != '\0') return -EINVAL;
- *tmp = PAGE_ALIGN(*tmp);
+ *tmp = PAGE_ALIGN64(*tmp); return 0; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Balbir Singh
Acked-byRe: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 16 lines · Andrea Righi
Review
Quoted 10 lines · Balbir Singh
+static int
memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp)(quoted diff) +8
-0+{ + *tmp = memparse(buf, &buf); + if (*buf != '\0') + return -EINVAL; + + *tmp = PAGE_ALIGN(*tmp); + return 0; +}We shouldn't use
PAGE_ALIGN()here, otherwise we limit the address space to 4GB on 32-bit architectures (that could be reasonable, because this is a per-cgroup limit and not per-process).
You mean un-reasonable?
Quoted 1 line
Signed-off-by Andrea Righi <[email protected]>
Seems fair enough.
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 17 lines · Balbir Singh
Quoted 15 lines · Andrea Righi
Review
Quoted 10 lines · Balbir Singh
+static int
memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp)(quoted diff) +8
-0+{ + *tmp = memparse(buf, &buf); + if (*buf != '\0') + return -EINVAL; + + *tmp = PAGE_ALIGN(*tmp); + return 0; +}We shouldn't use
PAGE_ALIGN()here, otherwise we limit the address space to 4GB on 32-bit architectures (that could be reasonable, because this is a per-cgroup limit and not per-process).
Quoted 1 line
You mean un-reasonable?
well... I mean, there would be no reason to apply this fix if it was a limit per-task on 32-bit. ;-)
-Andrea
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
In reply to Andrea RighiQuoted 34 lines · On Wed, 11 Jun 2008 19:10:40 +0200 (MEST) Andrea Righi…
Review
Quoted 9 lines · Balbir Singh
(quoted diff) +9
-0+static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp) +{ + *tmp = memparse(buf, &buf); + if (*buf != '\0') + return -EINVAL; + + *tmp = PAGE_ALIGN(*tmp); + return 0; +}We shouldn't use
PAGE_ALIGN()here, otherwise we limit the address space to 4GB on 32-bit architectures (that could be reasonable, because this is a per-cgroup limit and not per-process).Signed-off-by Andrea Righi <[email protected]>--- mm/memrlimitcgroup.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)mm/memrlimitcgroup.c +2
-0@@ -29,6 +29,8 @@#include <linux/res_counter.h> #include <linux/memrlimitcgroup.h> +#define PAGE_ALIGN64 (addr) (((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT) +struct cgroup_subsys memrlimit_cgroup_subsys;struct memrlimit_cgroup {
mm/memrlimitcgroup.c static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp) · line 132
Quoted 8 lines
mm/memrlimitcgroup.c +1
-1@@ -124,7 +126,7 @@ static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp)if (*buf !='\0' )return -EINVAL ; - *tmp =PAGE_ALIGN (*tmp); + *tmp =PAGE_ALIGN64 (*tmp);return 0 ; }
I don't beleive the change is needed.
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
that implementation will behaved as desired when passed a 64-bit addr?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 47 lines · Andrew Morton
Quoted 33 lines · On Wed, 11 Jun 2008 19:10:40 +0200 (MEST) Andrea Righi…
Review
Quoted 9 lines · Balbir Singh
(quoted diff) +9
-0+static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp) +{ + *tmp = memparse(buf, &buf); + if (*buf != '\0') + return -EINVAL; + + *tmp = PAGE_ALIGN(*tmp); + return 0; +}We shouldn't use
PAGE_ALIGN()here, otherwise we limit the address space to 4GB on 32-bit architectures (that could be reasonable, because this is a per-cgroup limit and not per-process).Signed-off-by Andrea Righi <[email protected]>--- mm/memrlimitcgroup.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)mm/memrlimitcgroup.c +2
-0@@ -29,6 +29,8 @@#include <linux/res_counter.h> #include <linux/memrlimitcgroup.h> +#define PAGE_ALIGN64 (addr) (((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT) +struct cgroup_subsys memrlimit_cgroup_subsys;struct memrlimit_cgroup {mm/memrlimitcgroup.c static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp) · line 132
Quoted 8 lines
mm/memrlimitcgroup.c +1
-1@@ -124,7 +126,7 @@ static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp)if (*buf !='\0' )return -EINVAL ; - *tmp =PAGE_ALIGN (*tmp); + *tmp =PAGE_ALIGN64 (*tmp);return 0 ; }I don't beleive the change is needed.
Quoted 3 lines
#define
PAGE_ALIGN(addr)(((addr)+PAGE_SIZE-1)&PAGE_MASK)that implementation will behaved as desired when passed a 64-bit addr?
If I'm not doing something wrong, here is what happens on my i386 box:
$ uname -m i686 $ cat 64-bit-page-align.c #include <stdio.h> #include <asm/page.h>
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
#define PAGE_ALIGN64(addr) (((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT)
#define SIZE ((1ULL << 32) - 1)
int main(int argc, char **argv)
{
unsigned long long good, bad;
good = (unsigned long long)PAGE_ALIGN64(SIZE);
bad = (unsigned long long)PAGE_ALIGN(SIZE);
fprintf(stdout, "good = %llu, bad = %llu\n", good, bad);
return 0;
}
$ gcc -O2 -o 64-bit-page-align 64-bit-page-align.c
$ ./64-bit-page-align
good = 4294967296, bad = 0
^^^^^^^
On a x86_64, instead, both PAGE_ALIGN()s work as expected:$ uname -m x86_64 $ gcc -O2 -o 64-bit-page-align 64-bit-page-align.c $ ./64-bit-page-align good = 4294967296, bad = 4294967296
At least we could add something like:
#ifdef CONFIG_32BIT
#define PAGE_ALIGN64(addr) (((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT) #else
#define PAGE_ALIGN64(addr) PAGE_ALIGN(addr)
#endif
But IMHO the single PAGE_ALIGN64() implementation is more clear.
-Andrea
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 66 lines · On Wed, 11 Jun 2008 22:17:12 +0200 Andrea Righi <[email protected]> wrote:
Quoted 47 lines · Andrew Morton
Quoted 33 lines · On Wed, 11 Jun 2008 19:10:40 +0200 (MEST) Andrea Righi…
Review
Quoted 9 lines · Balbir Singh
(quoted diff) +9
-0+static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp) +{ + *tmp = memparse(buf, &buf); + if (*buf != '\0') + return -EINVAL; + + *tmp = PAGE_ALIGN(*tmp); + return 0; +}We shouldn't use
PAGE_ALIGN()here, otherwise we limit the address space to 4GB on 32-bit architectures (that could be reasonable, because this is a per-cgroup limit and not per-process).Signed-off-by Andrea Righi <[email protected]>--- mm/memrlimitcgroup.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)mm/memrlimitcgroup.c +2
-0@@ -29,6 +29,8 @@#include <linux/res_counter.h> #include <linux/memrlimitcgroup.h> +#define PAGE_ALIGN64 (addr) (((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT) +struct cgroup_subsys memrlimit_cgroup_subsys;struct memrlimit_cgroup {mm/memrlimitcgroup.c static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp) · line 132
Quoted 8 lines
mm/memrlimitcgroup.c +1
-1@@ -124,7 +126,7 @@ static int memrlimit_cgroup_write_strategy(char *buf, unsigned long long *tmp)if (*buf !='\0' )return -EINVAL ; - *tmp =PAGE_ALIGN (*tmp); + *tmp =PAGE_ALIGN64 (*tmp);return 0 ; }I don't beleive the change is needed.
Quoted 3 lines
#define
PAGE_ALIGN(addr)(((addr)+PAGE_SIZE-1)&PAGE_MASK)that implementation will behaved as desired when passed a 64-bit addr?
If I'm not doing something wrong, here is what happens on my i386 box:
$ uname -m i686 $ cat 64-bit-page-align.c #include <stdio.h> #include <asm/page.h>#define
PAGE_ALIGN(addr)(((addr)+PAGE_SIZE-1)&PAGE_MASK)
#definePAGE_ALIGN64(addr)(((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT)#define SIZE ((1ULL << 32) - 1)
int
main(int argc, char **argv)
Quoted 15 lines
{
unsigned long long good, bad;
good = (unsigned long long)PAGE_ALIGN64(SIZE);
bad = (unsigned long long)PAGE_ALIGN(SIZE);
fprintf(stdout, "good = %llu, bad = %llu\n", good, bad);
return 0;
}
$ gcc -O2 -o 64-bit-page-align 64-bit-page-align.c
$ ./64-bit-page-align
good = 4294967296, bad = 0
^^^^^^^
On a x86_64, instead, both PAGE_ALIGN()s work as expected:That's weird. We have an expression which contains a combination of UL constants and ULL constants, and the compiler _isn't_ converting everything into ULL.
Quoted 8 lines
$ uname -m x86_64 $ gcc -O2 -o 64-bit-page-align 64-bit-page-align.c $ ./64-bit-page-align good = 4294967296, bad = 4294967296At least we could add something like:
Quoted 7 lines
#ifdef
CONFIG_32BIT
#definePAGE_ALIGN64(addr)(((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT) #else
#definePAGE_ALIGN64(addr)PAGE_ALIGN(addr)
#endifBut IMHO the single
PAGE_ALIGN64()implementation is more clear.
No, we should just fix PAGE_ALIGN. It should work correctly when passed a long-long. Otherwse it's just a timebomb.
This:
#define PAGE_ALIGN(addr) ({ \
typeof(addr) __size = PAGE_SIZE; \
typeof(addr) __mask = PAGE_MASK; \
(addr + __size - 1) & __mask; \
})(with a suitable comment) does what we want. I didn't check to see whether this causes the compiler to generate larger code, but it shouldn't.
If we go this way then first we should hoist the PAGE_ALIGN definitions out of include/asm-*/page.h and into, umm, include/linux/mm.h. That might cause build errors but from a bit of grepping around, only include/asm-arm/cacheflush.h is at risk, and it already includes linux/mm.h.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 21 lines · Andrew Morton
Quoted 9 lines
At least we could add something like:
#ifdef
CONFIG_32BIT
#definePAGE_ALIGN64(addr)(((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT) #else
#definePAGE_ALIGN64(addr)PAGE_ALIGN(addr)
#endifBut IMHO the single
PAGE_ALIGN64()implementation is more clear.No, we should just fix
PAGE_ALIGN. It should work correctly when passed a long-long. Otherwse it's just a timebomb.This:
#define PAGE_ALIGN(addr) ({ \ typeof(addr) __size = PAGE_SIZE; \ typeof(addr) __mask = PAGE_MASK; \ (addr + __size - 1) & __mask; \ })
Quoted 4 lines
(with a suitable comment) does what we want. I didn't check to see whether this causes the compiler to generate larger code, but it shouldn't.
No, it doesn't work. The problem seems to be in the PAGE_MASK definition (from include/asm-x86/page.h for example):
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1))
The "~" is performed on a 32-bit value, so everything in "and" with PAGE_MASK greater than 4GB will be truncated to the 32-bit boundary.
What do you think about the following?
#define PAGE_SIZE64 (1ULL << PAGE_SHIFT)
#define PAGE_MASK64 (~(PAGE_SIZE64 - 1))
#define PAGE_ALIGN(addr) ({ \
typeof(addr) __size = PAGE_SIZE; \
typeof(addr) __ret = (addr) + __size - 1; \
__ret > -1UL ? __ret & PAGE_MASK64 : __ret & PAGE_MASK; \
})-Andrea
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 30 lines · On Thu, 12 Jun 2008 00:47:27 +0200 Andrea Righi <[email protected]> wrote:
Quoted 21 lines · Andrew Morton
Quoted 9 lines
At least we could add something like:
#ifdef
CONFIG_32BIT
#definePAGE_ALIGN64(addr)(((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT) #else
#definePAGE_ALIGN64(addr)PAGE_ALIGN(addr)
#endifBut IMHO the single
PAGE_ALIGN64()implementation is more clear.No, we should just fix
PAGE_ALIGN. It should work correctly when passed a long-long. Otherwse it's just a timebomb.This:
#define PAGE_ALIGN(addr) ({ \ typeof(addr) __size = PAGE_SIZE; \ typeof(addr) __mask = PAGE_MASK; \ (addr + __size - 1) & __mask; \ })Quoted 4 lines
(with a suitable comment) does what we want. I didn't check to see whether this causes the compiler to generate larger code, but it shouldn't.
No, it doesn't work. The problem seems to be in the
PAGE_MASKdefinition (frominclude/asm-x86/page.hfor example):
Quoted 7 lines
/*
PAGE_SHIFTdetermines the page size */#define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1))The "~" is performed on a 32-bit value, so everything in "and" with
PAGE_MASKgreater than 4GB will be truncated to the 32-bit boundary.
OK, I oversimplified my testcase.
Quoted 10 lines
What do you think about the following?
#define
PAGE_SIZE64(1ULL <<PAGE_SHIFT)
#definePAGE_MASK64(~(PAGE_SIZE64 - 1))#define PAGE_ALIGN(addr) ({ \ typeof(addr) __size = PAGE_SIZE; \ typeof(addr) __ret = (addr) + __size - 1; \ __ret > -1UL ? __ret & PAGE_MASK64 : __ret & PAGE_MASK; \ })
Complex. And I'd worry about added code overhead.
What about
#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)
?
afaict ALIGN() tries to do the right thing, and if it doesn't, we should fix ALIGN().
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 54 lines · Andrew Morton
Quoted 28 lines · On Thu, 12 Jun 2008 00:47:27 +0200 Andrea Righi <[email protected]> wrote:
Quoted 20 lines · Andrew Morton
Quoted 9 lines
At least we could add something like:
#ifdef
CONFIG_32BIT
#definePAGE_ALIGN64(addr)(((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT) #else
#definePAGE_ALIGN64(addr)PAGE_ALIGN(addr)
#endifBut IMHO the single
PAGE_ALIGN64()implementation is more clear.No, we should just fix
PAGE_ALIGN. It should work correctly when passed a long-long. Otherwse it's just a timebomb.This:
#define PAGE_ALIGN(addr) ({ \ typeof(addr) __size = PAGE_SIZE; \ typeof(addr) __mask = PAGE_MASK; \ (addr + __size - 1) & __mask; \ })Quoted 4 lines
(with a suitable comment) does what we want. I didn't check to see whether this causes the compiler to generate larger code, but it shouldn't.
No, it doesn't work. The problem seems to be in the
PAGE_MASKdefinition (frominclude/asm-x86/page.hfor example):Quoted 7 lines
/*
PAGE_SHIFTdetermines the page size */#define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1))The "~" is performed on a 32-bit value, so everything in "and" with
PAGE_MASKgreater than 4GB will be truncated to the 32-bit boundary.OK, I oversimplified my testcase.
Quoted 10 lines
What do you think about the following?
#define
PAGE_SIZE64(1ULL <<PAGE_SHIFT)
#definePAGE_MASK64(~(PAGE_SIZE64 - 1))#define PAGE_ALIGN(addr) ({ \ typeof(addr) __size = PAGE_SIZE; \ typeof(addr) __ret = (addr) + __size - 1; \ __ret > -1UL ? __ret & PAGE_MASK64 : __ret & PAGE_MASK; \ })Complex. And I'd worry about added code overhead.
Quoted 8 lines
What about
#define
PAGE_ALIGN(addr)ALIGN(addr, PAGE_SIZE)?
afaict
ALIGN()tries to do the right thing, and if it doesn't, we should fixALIGN().
Good! Much simpler.
-Andrea
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
In reply to Andrew MortonQuoted 8 lines · Andrew Morton
#define
PAGE_ALIGN(addr)ALIGN(addr, PAGE_SIZE)?
afaict
ALIGN()tries to do the right thing, and if it doesn't, we should fixALIGN().
That should do the right thing, provided there are no duplicate ALIGN defintions elsewhere
kernel.h has
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
Which seems like the correct thing, since we use typeof(x) for (a) - 1.
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 12 lines · Balbir Singh
Quoted 7 lines · Andrew Morton
#define
PAGE_ALIGN(addr)ALIGN(addr, PAGE_SIZE)?
afaict
ALIGN()tries to do the right thing, and if it doesn't, we should fixALIGN().That should do the right thing, provided there are no duplicate ALIGN defintions elsewhere
Quoted 7 lines
kernel.hhas#define
ALIGN(x,a)__ALIGN_MASK(x,(typeof(x))(a)-1)
#define__ALIGN_MASK(x,mask)(((x)+(mask))&~(mask))Which seems like the correct thing, since we use typeof(x) for (a) - 1.
OK, I'm going to do some builds and tests on my i386 and x86_64 boxes with the following patch. I'm sure this will break something and I don't know if moving PAGE_ALIGN() out of asm-*/page.h is the right way.
I'll keep you informed and post an updated version in case I'll find obvious errors.
-Andrea
---
Properly handle 64-bit values with PAGE_ALIGN() on 32-bit architectures.
For example:
u64 val = PAGE_ALIGN(size);
is broken on 32-bit architectures if size is greater than 4GB.
The problem resides in PAGE_MASK definition (from include/asm-x86/page.h for example):
#define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1))
...
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
The "~" is performed on a 32-bit value, so everything in "and" with PAGE_MASK greater than 4GB will be truncated to the 32-bit boundary.
Also move the PAGE_ALIGN() definitions out of include/asm-*/page.h in include/linux/mm.h.
---
arch/powerpc/boot/page.h | 3 --- drivers/pci/intel-iommu.h | 2 +- include/asm-alpha/page.h | 3 --- include/asm-arm/page-nommu.h | 4 +--- include/asm-arm/page.h | 3 --- include/asm-avr32/page.h | 3 --- include/asm-blackfin/page.h | 3 --- include/asm-cris/page.h | 3 --- include/asm-frv/page.h | 3 --- include/asm-h8300/page.h | 3 --- include/asm-ia64/page.h | 1 - include/asm-m32r/page.h | 3 --- include/asm-m68k/page.h | 3 --- include/asm-m68knommu/page.h | 3 --- include/asm-mips/page.h | 3 --- include/asm-mn10300/page.h | 3 --- include/asm-parisc/page.h | 4 ---- include/asm-powerpc/page.h | 3 --- include/asm-ppc/page.h | 4 ---- include/asm-s390/page.h | 3 --- include/asm-sh/page.h | 3 --- include/asm-sparc/page.h | 3 --- include/asm-sparc64/page.h | 3 --- include/asm-um/page.h | 3 --- include/asm-v850/page.h | 6 ------ include/asm-x86/page.h | 3 --- include/asm-xtensa/page.h | 2 -- include/linux/mm.h | 4 ++++ 28 files changed, 6 insertions(+), 81 deletions(-)
arch/powerpc/boot/page.h +0 -0
@@ -28,7 +28,4 @@
/* align addr on a size boundary - adjust address up if needed */
#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
-
#endif /* _PPC_BOOT_PAGE_H */
drivers/pci/intel-iommu.h +0 -0
@@ -35,7 +35,7 @@
#define PAGE_SHIFT_4K (12)
#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K)
#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K)
-#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K)
+#define PAGE_ALIGN_4K(addr) ALIGN(addr, PAGE_SIZE_4K)
#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K)
#define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK)
include/asm-alpha/page.h +0 -0
@@ -80,9 +80,6 @@ typedef struct page *pgtable_t;
#endif /* !__ASSEMBLY__ */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
#ifndef CONFIG_DISCONTIGMEM
include/asm-arm/page-nommu.h +1 -0
@@ -7,6 +7,7 @@* it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +
#ifndef _ASMARM_PAGE_NOMMU_H
#define _ASMARM_PAGE_NOMMU_H
@@ -42,9 +43,6 @@ typedef unsigned long pgprot_t;
#define __pmd(x) (x)
#define __pgprot(x) (x)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
extern unsigned long memory_start;
extern unsigned long memory_end;
include/asm-arm/page.h +0 -0
@@ -15,9 +15,6 @@
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#ifndef __ASSEMBLY__
#ifndef CONFIG_MMU
include/asm-avr32/page.h +0 -0
@@ -57,9 +57,6 @@ static inline int get_order(unsigned long size)
#endif /* !__ASSEMBLY__ */
-/* Align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
/*
* The hardware maps the virtual addresses 0x80000000 -> 0x9fffffff
* permanently to the physical addresses 0x00000000 -> 0x1fffffff when
include/asm-blackfin/page.h +0 -0
@@ -51,9 +51,6 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
extern unsigned long memory_start;
extern unsigned long memory_end;
include/asm-cris/page.h +0 -0
@@ -60,9 +60,6 @@ typedef struct page *pgtable_t;
#define page_to_phys(page) __pa((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#ifndef __ASSEMBLY__
#endif /* __ASSEMBLY__ */
include/asm-frv/page.h +0 -0
@@ -40,9 +40,6 @@ typedef struct page *pgtable_t;
#define __pgprot(x) ((pgprot_t) { (x) } )
#define PTE_MASK PAGE_MASK
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
#define devmem_is_allowed(pfn) 1
#define __pa(vaddr) virt_to_phys((void *) (unsigned long) (vaddr))
include/asm-h8300/page.h +0 -0
@@ -43,9 +43,6 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
extern unsigned long memory_start;
extern unsigned long memory_end;
include/asm-ia64/page.h +0 -0
@@ -40,7 +40,6 @@
#define PAGE_SIZE (__IA64_UL_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
#define PERCPU_PAGE_SHIFT 16 /* log2() of max. size of per-CPU area */
#define PERCPU_PAGE_SIZE (__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT)
include/asm-m32r/page.h +0 -0
@@ -41,9 +41,6 @@ typedef struct page *pgtable_t;
#endif /* !__ASSEMBLY__ */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
/*
* This handles the memory map.. We could make this a config
* option, but too many people screw it up, and too few need
include/asm-m68k/page.h +0 -0
@@ -103,9 +103,6 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#endif /* !__ASSEMBLY__ */
#include <asm/page_offset.h>
include/asm-m68knommu/page.h +0 -0
@@ -43,9 +43,6 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
extern unsigned long memory_start;
extern unsigned long memory_end;
include/asm-mips/page.h +0 -0
@@ -134,9 +134,6 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#endif /* !__ASSEMBLY__ */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
/*
* __pa()/__va() should be used only during mem init. */
include/asm-mn10300/page.h +0 -0
@@ -61,9 +61,6 @@ typedef struct page *pgtable_t;
#endif /* !__ASSEMBLY__ */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
/*
* This handles the memory map.. We could make this a config
* option, but too many people screw it up, and too few need
include/asm-parisc/page.h +0 -0
@@ -119,10 +119,6 @@ extern int npmem_ranges;
#define PMD_ENTRY_SIZE (1UL << BITS_PER_PMD_ENTRY)
#define PTE_ENTRY_SIZE (1UL << BITS_PER_PTE_ENTRY)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
-
#define LINUX_GATEWAY_SPACE 0
/* This governs the relationship between virtual and physical addresses.
include/asm-powerpc/page.h +0 -0
@@ -119,9 +119,6 @@ extern phys_addr_t kernstart_addr;
/* align addr on a size boundary - adjust address up if needed */
#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
-
/*
* Don't compare things with KERNELBASE or PAGE_OFFSET to test for
* "kernelness", use is_kernel_addr() - it should do what you want.
include/asm-ppc/page.h +0 -0
@@ -43,10 +43,6 @@ typedef unsigned long pte_basic_t;
/* align addr on a size boundary - adjust address up if needed */
#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
-
-
#undef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
include/asm-s390/page.h +0 -0
@@ -138,9 +138,6 @@ void arch_alloc_page(struct page *page, int order);
#endif /* !__ASSEMBLY__ */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#define __PAGE_OFFSET 0x0UL #define PAGE_OFFSET 0x0UL #define __pa(x) (unsigned long)(x)
include/asm-sh/page.h +0 -0
@@ -22,9 +22,6 @@
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PTE_MASK PAGE_MASK
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
#define HPAGE_SHIFT 16
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K)
include/asm-sparc/page.h +0 -0
@@ -136,9 +136,6 @@ BTFIXUPDEF_SETHI(sparc_unmapped_base)
#endif /* !(__ASSEMBLY__) */
-/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -
#define PAGE_OFFSET 0xf0000000
#ifndef __ASSEMBLY__
extern unsigned long phys_base;
include/asm-sparc64/page.h +0 -0
@@ -110,9 +110,6 @@ typedef struct page *pgtable_t;
#endif /* !(__ASSEMBLY__) */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
/* We used to stick this into a hard-coded global register (%g4)
* but that does not make sense anymore.
*/
include/asm-um/page.h +0 -0
@@ -92,9 +92,6 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
extern unsigned long uml_physmem;
#define PAGE_OFFSET (uml_physmem)
include/asm-v850/page.h +0 -0
@@ -16,7 +16,6 @@
#include <asm/machdep.h>
-
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
@@ -93,11 +92,6 @@ typedef unsigned long pgprot_t;
#endif /* !__ASSEMBLY__ */
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
-
/* No current v850 processor has virtual memory. */
#define __virt_to_phys(addr) (addr)
#define __phys_to_virt(addr) (addr)
include/asm-x86/page.h +0 -0
@@ -29,9 +29,6 @@
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#ifndef __ASSEMBLY__
#include <linux/types.h>
#endif
include/asm-xtensa/page.h +0 -0
@@ -26,13 +26,11 @@
/*
* PAGE_SHIFT determines the page size
- * PAGE_ALIGN(x) aligns the pointer to the (next) page boundary */
#define PAGE_SHIFT 12
#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE - 1) & PAGE_MASK)
#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR
#define MAX_MEM_PFN XCHAL_KSEG_SIZE
include/linux/mm.h +0 -0
@@ -9,6 +9,7 @@
#include <linux/list.h>
#include <linux/mmzone.h>
#include <linux/rbtree.h>
+#include <linux/kernel.h>
#include <linux/prio_tree.h>
#include <linux/debug_locks.h>
#include <linux/mm_types.h>
@@ -41,6 +42,9 @@ extern unsigned long mmap_min_addr;
#define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
+/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE) +
/*
* Linux kernel virtual memory manager primitives.
* The idea being to have a "virtual" mm in the same way
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 16 lines · On Thu, 12 Jun 2008 10:52:13 +0200 (MEST) Andrea Righi…
Quoted 15 lines · Balbir Singh
Quoted 7 lines · Andrew Morton
#define
PAGE_ALIGN(addr)ALIGN(addr, PAGE_SIZE)?
afaict
ALIGN()tries to do the right thing, and if it doesn't, we should fixALIGN().That should do the right thing, provided there are no duplicate ALIGN defintions elsewhere
kernel.hhas
Quoted 8 lines
Quoted 4 lines
#define
ALIGN(x,a)__ALIGN_MASK(x,(typeof(x))(a)-1)
#define__ALIGN_MASK(x,mask)(((x)+(mask))&~(mask))Which seems like the correct thing, since we use typeof(x) for (a) - 1.
OK, I'm going to do some builds and tests on my i386 and
x86_64boxes with the following patch. I'm sure this will break something and I don't know if movingPAGE_ALIGN()out ofasm-*/page.his the right way.
Thanks. Looks good from here.
Quoted 14 lines
...
include/linux/mm.h +1
-0@@ -9,6 +9,7 @@#include <linux/list.h> #include <linux/mmzone.h> #include <linux/rbtree.h> +#include <linux/kernel.h> #include <linux/prio_tree.h> #include <linux/debug_locks.h> #include <linux/mm_types.h>
include/linux/mm.h extern unsigned long mmap_min_addr; · line 50
Quoted 9 lines
include/linux/mm.h +3
-0@@ -41,6 +42,9 @@ extern unsigned long mmap_min_addr;#define nth_page (page,n) pfn_to_page(page_to_pfn((page)) + (n)) +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN (addr) ALIGN(addr, PAGE_SIZE) +/* * Linux kernel virtual memory manager primitives. * The idea being to have a "virtual" mm in the same way
You don't really need the #include <linux/kernel.h> there. As long as all callsites which _use_ PAGE_ALIGN are including kernel.h via some means (and they surely will be) then things will work OK.
But it won't hurt. We're already picking up kernel.h there via mmzone.h->spinlock.h and probably 100 other routes. One more won't make a lot of difference ;)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 2/4] Setup the memrlimit controller (v5)
Quoted 14 lines · Andrew Morton
Quoted 14 lines
include/linux/mm.h +1
-0@@ -9,6 +9,7 @@#include <linux/list.h> #include <linux/mmzone.h> #include <linux/rbtree.h> +#include <linux/kernel.h> #include <linux/prio_tree.h> #include <linux/debug_locks.h> #include <linux/mm_types.h> @@ -41,6 +42,9 @@ extern unsigned long mmap_min_addr;#define nth_page (page,n) pfn_to_page(page_to_pfn((page)) + (n))
Quoted 10 lines
include/linux/mm.h extern unsigned long mmap_min_addr; · line 50
Quoted 6 lines
include/linux/mm.h +3
-0+/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN (addr) ALIGN(addr, PAGE_SIZE) +/* * Linux kernel virtual memory manager primitives. * The idea being to have a "virtual" mm in the same way You don't really need the #include <
linux/kernel.h> there. As long as all callsites which _use_PAGE_ALIGNare includingkernel.hvia some means (and they surely will be) then things will work OK.
OK, testing without linux/kernel.h inclusion.
-Andrea
Quoted 4 lines
But it won't hurt. We're already picking up
kernel.hthere viammzone.h->spinlock.hand probably 100 other routes. One more won't make a lot of difference ;)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/1 PAGE_ALIGN(): correctly handle 64-bit values on 32-bit architectures
In reply to Andrew MortonI've tested the following patch on a i386 box with my usual .config and everything seems fine. I also tested allmodconfig and some randconfig builds and I've not seen any evident error.
I'll repeat the tests tonight on a x86_64. Other architectures should be tested as well...
Patch is against 2.6.25-rc5-mm3.
-Andrea
---
On 32-bit architectures PAGE_ALIGN() truncates 64-bit values to the 32-bit boundary. For example:
u64 val = PAGE_ALIGN(size);
always returns a value < 4GB even if size is greater than 4GB.
The problem resides in PAGE_MASK definition (from include/asm-x86/page.h for example):
#define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1))
...
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
The "~" is performed on a 32-bit value, so everything in "and" with PAGE_MASK greater than 4GB will be truncated to the 32-bit boundary. Using the ALIGN() macro seems to be the right way, because it uses typeof(addr) for the mask.
Also move the PAGE_ALIGN() definitions out of include/asm-*/page.h in include/linux/mm.h.
See also lkml discussion: http://lkml.org/lkml/2008/6/11/237
---
arch/powerpc/boot/page.h +0 -0
@@ -28,7 +28,4 @@
/* align addr on a size boundary - adjust address up if needed */
#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
-
#endif /* _PPC_BOOT_PAGE_H */
arch/sparc64/kernel/iommu_common.h +0 -0
@@ -23,7 +23,7 @@
#define IO_PAGE_SHIFT 13
#define IO_PAGE_SIZE (1UL << IO_PAGE_SHIFT)
#define IO_PAGE_MASK (~(IO_PAGE_SIZE-1))
-#define IO_PAGE_ALIGN(addr) (((addr)+IO_PAGE_SIZE-1)&IO_PAGE_MASK)
+#define IO_PAGE_ALIGN(addr) ALIGN(addr, IO_PAGE_SIZE)
#define IO_TSB_ENTRIES (128*1024)
#define IO_TSB_SIZE (IO_TSB_ENTRIES * 8)
drivers/char/random.c +0 -0
@@ -236,6 +236,7 @@
#include <linux/fs.h>
#include <linux/genhd.h>
#include <linux/interrupt.h>
+#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/percpu.h>
#include <linux/cryptohash.h>
drivers/media/video/pvrusb2/pvrusb2-ioread.c +0 -0
@@ -22,6 +22,7 @@
#include "pvrusb2-debug.h"
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
drivers/media/video/videobuf-core.c +0 -0
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
drivers/pci/intel-iommu.h +0 -0
@@ -35,7 +35,7 @@
#define PAGE_SHIFT_4K (12)
#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K)
#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K)
-#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K)
+#define PAGE_ALIGN_4K(addr) ALIGN(addr, PAGE_SIZE_4K)
#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K)
#define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK)
include/asm-alpha/page.h +0 -0
@@ -80,9 +80,6 @@ typedef struct page *pgtable_t;
#endif /* !__ASSEMBLY__ */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
#ifndef CONFIG_DISCONTIGMEM
include/asm-arm/page.h +0 -0
@@ -15,9 +15,6 @@
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#ifndef __ASSEMBLY__
#ifndef CONFIG_MMU
include/asm-arm/page-nommu.h +1 -0
@@ -7,6 +7,7 @@* it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +
#ifndef _ASMARM_PAGE_NOMMU_H
#define _ASMARM_PAGE_NOMMU_H
@@ -42,9 +43,6 @@ typedef unsigned long pgprot_t;
#define __pmd(x) (x)
#define __pgprot(x) (x)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
extern unsigned long memory_start;
extern unsigned long memory_end;
include/asm-avr32/page.h +0 -0
@@ -57,9 +57,6 @@ static inline int get_order(unsigned lon
#endif /* !__ASSEMBLY__ */
-/* Align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
/*
* The hardware maps the virtual addresses 0x80000000 -> 0x9fffffff
* permanently to the physical addresses 0x00000000 -> 0x1fffffff when
include/asm-blackfin/page.h +0 -0
@@ -51,9 +51,6 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
extern unsigned long memory_start;
extern unsigned long memory_end;
include/asm-cris/page.h +0 -0
@@ -60,9 +60,6 @@ typedef struct page *pgtable_t;
#define page_to_phys(page) __pa((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#ifndef __ASSEMBLY__
#endif /* __ASSEMBLY__ */
include/asm-frv/page.h +0 -0
@@ -40,9 +40,6 @@ typedef struct page *pgtable_t;
#define __pgprot(x) ((pgprot_t) { (x) } )
#define PTE_MASK PAGE_MASK
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
#define devmem_is_allowed(pfn) 1
#define __pa(vaddr) virt_to_phys((void *) (unsigned long) (vaddr))
include/asm-h8300/page.h +0 -0
@@ -43,9 +43,6 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
extern unsigned long memory_start;
extern unsigned long memory_end;
include/asm-ia64/page.h +0 -0
@@ -40,7 +40,6 @@
#define PAGE_SIZE (__IA64_UL_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
#define PERCPU_PAGE_SHIFT 16 /* log2() of max. size of per-CPU area */
#define PERCPU_PAGE_SIZE (__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT)
include/asm-m32r/page.h +0 -0
@@ -41,9 +41,6 @@ typedef struct page *pgtable_t;
#endif /* !__ASSEMBLY__ */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
/*
* This handles the memory map.. We could make this a config
* option, but too many people screw it up, and too few need
include/asm-m68k/dvma.h +0 -0
@@ -13,7 +13,7 @@
#define DVMA_PAGE_SHIFT 13
#define DVMA_PAGE_SIZE (1UL << DVMA_PAGE_SHIFT)
#define DVMA_PAGE_MASK (~(DVMA_PAGE_SIZE-1))
-#define DVMA_PAGE_ALIGN(addr) (((addr)+DVMA_PAGE_SIZE-1)&DVMA_PAGE_MASK)
+#define DVMA_PAGE_ALIGN(addr) ALIGN(addr, DVMA_PAGE_SIZE)
extern void dvma_init(void);
extern int dvma_map_iommu(unsigned long kaddr, unsigned long baddr,
include/asm-m68k/page.h +0 -0
@@ -103,9 +103,6 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#endif /* !__ASSEMBLY__ */
#include <asm/page_offset.h>
include/asm-m68knommu/page.h +0 -0
@@ -43,9 +43,6 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
extern unsigned long memory_start;
extern unsigned long memory_end;
include/asm-mips/page.h +0 -0
@@ -134,9 +134,6 @@ typedef struct { unsigned long pgprot; }
#endif /* !__ASSEMBLY__ */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
/*
* __pa()/__va() should be used only during mem init. */
include/asm-mn10300/page.h +0 -0
@@ -61,9 +61,6 @@ typedef struct page *pgtable_t;
#endif /* !__ASSEMBLY__ */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
-
/*
* This handles the memory map.. We could make this a config
* option, but too many people screw it up, and too few need
include/asm-parisc/page.h +0 -0
@@ -119,10 +119,6 @@ extern int npmem_ranges;
#define PMD_ENTRY_SIZE (1UL << BITS_PER_PMD_ENTRY)
#define PTE_ENTRY_SIZE (1UL << BITS_PER_PTE_ENTRY)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
-
#define LINUX_GATEWAY_SPACE 0
/* This governs the relationship between virtual and physical addresses.
include/asm-powerpc/page.h +0 -0
@@ -119,9 +119,6 @@ extern phys_addr_t kernstart_addr;
/* align addr on a size boundary - adjust address up if needed */
#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
-
/*
* Don't compare things with KERNELBASE or PAGE_OFFSET to test for
* "kernelness", use is_kernel_addr() - it should do what you want.
include/asm-ppc/page.h +0 -0
@@ -43,10 +43,6 @@ typedef unsigned long pte_basic_t;
/* align addr on a size boundary - adjust address up if needed */
#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
-
-
#undef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
include/asm-s390/page.h +0 -0
@@ -138,9 +138,6 @@ void arch_alloc_page(struct page *page,
#endif /* !__ASSEMBLY__ */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#define __PAGE_OFFSET 0x0UL #define PAGE_OFFSET 0x0UL #define __pa(x) (unsigned long)(x)
include/asm-sh/page.h +0 -0
@@ -24,9 +24,6 @@
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PTE_MASK PAGE_MASK
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
#define HPAGE_SHIFT 16
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K)
include/asm-sparc/page.h +0 -0
@@ -136,9 +136,6 @@ BTFIXUPDEF_SETHI(sparc_unmapped_base)
#endif /* !(__ASSEMBLY__) */
-/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -
#define PAGE_OFFSET 0xf0000000
#ifndef __ASSEMBLY__
extern unsigned long phys_base;
include/asm-sparc64/page.h +0 -0
@@ -110,9 +110,6 @@ typedef struct page *pgtable_t;
#endif /* !(__ASSEMBLY__) */
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
/* We used to stick this into a hard-coded global register (%g4)
* but that does not make sense anymore.
*/
include/asm-um/page.h +0 -0
@@ -92,9 +92,6 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
extern unsigned long uml_physmem;
#define PAGE_OFFSET (uml_physmem)
include/asm-x86/page.h +0 -0
@@ -31,9 +31,6 @@
#define HUGE_MAX_HSTATE 2
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
#ifndef __ASSEMBLY__
#include <linux/types.h>
#endif
include/asm-xtensa/page.h +0 -0
@@ -26,13 +26,11 @@
/*
* PAGE_SHIFT determines the page size
- * PAGE_ALIGN(x) aligns the pointer to the (next) page boundary */
#define PAGE_SHIFT 12
#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE - 1) & PAGE_MASK)
#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR
#define MAX_MEM_PFN XCHAL_KSEG_SIZE
include/linux/mm.h +0 -0
@@ -41,6 +41,9 @@ extern unsigned long mmap_min_addr;
#define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
+/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE) +
/*
* Linux kernel virtual memory manager primitives.
* The idea being to have a "virtual" mm in the same way
sound/core/info.c +0 -0
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/time.h>
+#include <linux/mm.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
#include <sound/core.h>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH -mm] PAGE_ALIGN(): correctly handle 64-bit values on 32-bit architectures
Quoted 6 lines · Andrea Righi
I've tested the following patch on a i386 box with my usual .config and everything seems fine. I also tested allmodconfig and some randconfig builds and I've not seen any evident error.
I'll repeat the tests tonight on a
x86_64. Other architectures should be tested as well...
x86_64 allmodconfig build failed due to a missing #include <linux/mm.h> in arch/x86/kernel/module_64.c.
Following patch resolves (on top of the previous one).
Except this, no errors for x86_64.
---
arch/x86/kernel/module_64.c +0 -0
@@ -22,6 +22,7 @@
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
+#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/bug.h>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH -mm] PAGE_ALIGN(): correctly handle 64-bit values on 32-bit architectures
In reply to Andrea RighiQuoted 10 lines · Andrea Righi
I've tested the following patch on a i386 box with my usual .config and everything seems fine. I also tested allmodconfig and some randconfig builds and
I've not seen any evident error.I'll repeat the tests tonight on a
x86_64. Other architectures should be tested
as well...Patch is against 2.6.25-rc5-mm3.
Hi, Andrea,
CC'ing linux-arch. I have a power box, but it's busy. I'll try and test your patch on it as soon as I can get hold of it.
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH -mm] PAGE_ALIGN(): correctly handle 64-bit values on 32-bit architectures
Quoted 10 lines · Balbir Singh
Quoted 9 lines · Andrea Righi
I've tested the following patch on a i386 box with my usual .config and everything seems fine. I also tested allmodconfig and some randconfig builds and
I've not seen any evident error.I'll repeat the tests tonight on a
x86_64. Other architectures should be tested
as well...
Quoted 8 lines
Quoted 1 line
Patch is against 2.6.25-rc5-mm3.
Hi, Andrea,
CC'ing linux-arch. I have a power box, but it's busy. I'll try and test your patch on it as soon as I can get hold of it.
It passes allmodconfig and a randconfig build on ia64, but I have no more access to the machine to do more test.
PATCH 3/4 cgroup mm owner callback changes to add task info (v5)
In reply to Balbir SinghThis patch adds an additional field to the mm_owner callbacks. This field is required to get to the mm that changed. Hold mmap_sem in write mode before calling the mm_owner_changed callback
---
include/linux/cgroup.h | 3 ++- kernel/cgroup.c | 4 +++- kernel/exit.c | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-)
include/linux/cgroup.h renamed from include/linux/cgroup.h~cgroup-add-task-to-mm-owner-callbacks +2 -1
@@ -310,7 +310,8 @@ struct cgroup_subsys {*/ void (*mm_owner_changed)(struct cgroup_subsys *ss,struct cgroup *old, -struct cgroup *new); +struct cgroup *new, +struct task_struct *p);int subsys_id;int active;int disabled;
kernel/cgroup.c renamed from kernel/cgroup.c~cgroup-add-task-to-mm-owner-callbacks +3 -1
@@ -2758,6 +2758,8 @@ void cgroup_fork_callbacks(struct task_s* Called on every change to mm->owner. mm_init_owner() does not * invoke this routine, since it assigns the mm->owner the first time * and does not change it. +* +* The callbacks are invoked with mmap_sem held in read mode. */ void cgroup_mm_owner_callbacks (struct task_struct *old,struct task_struct *new) {
@@ -2772,7 +2774,7 @@ void cgroup_mm_owner_callbacks(struct taif (oldcgrp == newcgrp)continue ;if (ss->mm_owner_changed) - ss->mm_owner_changed (ss, oldcgrp, newcgrp); + ss->mm_owner_changed (ss, oldcgrp, newcgrp, new); } } }
kernel/exit.c renamed from kernel/exit.c~cgroup-add-task-to-mm-owner-callbacks +3 -0
@@ -621,6 +621,7 @@ retry: assign_new_owner:BUG_ON (c == p);get_task_struct (c); +down_write (&mm->mmap_sem);/* * The task_lock protects c->mm from changing. * We always want mm->owner->mm == mm
@@ -634,12 +635,14 @@ assign_new_owner:if (c->mm != mm) {task_unlock (c);put_task_struct (c); +up_write (&mm->mmap_sem); goto retry; }cgroup_mm_owner_callbacks (mm->owner, c); mm->owner = c;task_unlock (c);put_task_struct (c); + up_write(&mm->mmap_sem); }#endif /* CONFIG_MM_OWNER */
_
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [-mm][PATCH 3/4] cgroup mm owner callback changes to add task info (v5)
Quoted 8 lines · On Wed, 21 May 2008 20:59:59 +0530 Balbir Singh <[email protected]>…
This patch adds an additional field to the
mm_ownercallbacks. This field is required to get to the mm that changed. Holdmmap_semin write mode before calling themm_owner_changedcallback...
+ * The callbacks are invoked with
mmap_semheld in read mode.
Is that true?
Review
Quoted 3 lines
(quoted diff) +1
-0+ down_write(&mm->mmap_sem); cgroup_mm_owner_callbacks(mm->owner, c);
Looks like write-mode to me?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 3/4] cgroup mm owner callback changes to add task info (v5)
Quoted 10 lines · Andrew Morton
Quoted 7 lines · On Wed, 21 May 2008 20:59:59 +0530 Balbir Singh <[email protected]>…
This patch adds an additional field to the
mm_ownercallbacks. This field is required to get to the mm that changed. Holdmmap_semin write mode before calling themm_owner_changedcallback...
+ * The callbacks are invoked with
mmap_semheld in read mode.
Quoted 7 lines
Is that true?
Review
Quoted 3 lines
(quoted diff) +1
-0+ down_write(&mm->mmap_sem); cgroup_mm_owner_callbacks(mm->owner, c);Looks like write-mode to me?
Yes, obsolete comment. Will fix.
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 4/4 Add memrlimit controller accounting and control (v5)
In reply to Balbir SinghThis patch adds support for accounting and control of virtual address space limits. The accounting is done via the rlimit_cgroup_(un)charge_as functions. The core of the accounting takes place during fork time in copy_process(), may_expand_vm(), remove_vma_list() and exit_mmap().
Changelog v5->v4
Move specific hooks in code to insert_vm_struct
Use mmap_sem to protect mm->owner from changing and mm->owner from changing cgroups.
---
arch/x86/kernel/ptrace.c | 18 +++++-- include/linux/memrlimitcgroup.h | 21 +++++++++ kernel/fork.c | 8 +++ mm/memrlimitcgroup.c | 92 ++++++++++++++++++++++++++++++++++++++++ mm/mmap.c | 17 ++++++- 5 files changed, 149 insertions(+), 7 deletions(-)
diff -puN arch/ia64/kernel/perfmon.c~memrlimit-controller-address-space-accounting-and-control arch/ia64/kernel/perfmon.c diff -puN arch/x86/kernel/ds.c~memrlimit-controller-address-space-accounting-and-control arch/x86/kernel/ds.c diff -puN fs/exec.c~memrlimit-controller-address-space-accounting-and-control fs/exec.c
include/linux/memrlimitcgroup.h renamed from include/linux/memrlimitcgroup.h~memrlimit-controller-address-space-accounting-and-control +21 -0
@@ -16,4 +16,25 @@#ifndef LINUX_MEMRLIMITCGROUP_H #define LINUX_MEMRLIMITCGROUP_H +#ifdef CONFIG_CGROUP_MEMRLIMIT_CTLR + +int memrlimit_cgroup_charge_as (struct mm_struct *mm,unsigned long nr_pages); +void memrlimit_cgroup_uncharge_as (struct mm_struct *mm,unsigned long nr_pages); + +#else /* !CONFIG_CGROUP_RLIMIT_CTLR */ + +static inline int +memrlimit_cgroup_charge_as (struct mm_struct *mm,unsigned long nr_pages) +{ +return 0 ; +} + +static inline void +memrlimit_cgroup_uncharge_as (struct mm_struct *mm,unsigned long nr_pages) +{ +} + +#endif /* CONFIG_CGROUP_RLIMIT_CTLR */ + +#endif /* LINUX_MEMRLIMITCGROUP_H */
kernel/fork.c renamed from kernel/fork.c~memrlimit-controller-address-space-accounting-and-control +8 -0
@@ -54,6 +54,7 @@#include <linux/tty.h> #include <linux/proc_fs.h> #include <linux/blkdev.h> +#include <linux/memrlimitcgroup.h> #include <asm/pgtable.h> #include <asm/pgalloc.h>
@@ -267,6 +268,7 @@ static int dup_mmap(struct mm_struct *mm mm->total_vm -= pages;vm_stat_account (mm, mpnt->vm_flags, mpnt->vm_file, -pages); +memrlimit_cgroup_uncharge_as (mm, pages);continue ; } charge =0 ;
@@ -596,6 +598,12 @@ static int copy_mm(unsigned long clone_fatomic_inc (&oldmm->mm_users); mm = oldmm; goto good_mm; + }else { +down_write (&oldmm->mmap_sem); + retval =memrlimit_cgroup_charge_as (oldmm, oldmm->total_vm); +up_write (&oldmm->mmap_sem); +if (retval) + goto fail_nomem; } retval = -ENOMEM ;
mm/memrlimitcgroup.c renamed from mm/memrlimitcgroup.c~memrlimit-controller-address-space-accounting-and-control +92 -0
109 lines not on this page · raw message
mm/mmap.c renamed from mm/mmap.c~memrlimit-controller-address-space-accounting-and-control +15 -2
@@ -26,6 +26,7 @@#include <linux/mount.h> #include <linux/mempolicy.h> #include <linux/rmap.h> +#include <linux/memrlimitcgroup.h> #include <asm/uaccess.h> #include <asm/cacheflush.h>
@@ -1730,6 +1731,7 @@ static void remove_vma_list(struct mm_stlong nrpages =vma_pages (vma); mm->total_vm -= nrpages; +memrlimit_cgroup_uncharge_as (mm, nrpages);if (vma->vm_flags &VM_LOCKED ) mm->locked_vm -= nrpages;vm_stat_account (mm, vma->vm_flags, vma->vm_file, -nrpages);
@@ -2056,6 +2058,7 @@ void exit_mmap(struct mm_struct *mm)/* Use -1 here to ensure all VMAs in the mm are unmapped */ end =unmap_vmas (&tlb, vma,0 ,-1 , &nr_accounted,NULL );vm_unacct_memory (nr_accounted); +memrlimit_cgroup_uncharge_as (mm, mm->total_vm);free_pgtables (&tlb, vma,FIRST_USER_ADDRESS ,0 );tlb_finish_mmu (tlb,0 , end);
@@ -2078,6 +2081,9 @@ int insert_vm_struct(struct mm_struct *struct vm_area_struct * __vma, * prev;struct rb_node ** rb_link, * rb_parent; +if (memrlimit_cgroup_charge_as (mm,vma_pages (vma))) +return -ENOMEM ; +/* * The vm_pgoff of a purely anonymous vma should be irrelevant * until its first write fault, when page's anon_vma and index
@@ -2096,12 +2102,15 @@ int insert_vm_struct(struct mm_struct * } __vma =find_vma_prepare (mm,vma->vm_start,&prev,&rb_link,&rb_parent);if (__vma && __vma->vm_start < vma->vm_end) -return -ENOMEM ; + goto err;if ((vma->vm_flags &VM_ACCOUNT ) &&security_vm_enough_memory_mm (mm,vma_pages (vma))) -return -ENOMEM ; + goto err;vma_link (mm, vma, prev, rb_link, rb_parent);return 0 ; +err: +memrlimit_cgroup_uncharge_as (mm,vma_pages (vma)); +return -ENOMEM ; }/*
@@ -2174,6 +2183,10 @@ int may_expand_vm(struct mm_struct *mm,if (cur + npages > lim)return 0 ; + +if (memrlimit_cgroup_charge_as (mm, npages)) +return 0 ; +return 1 ; }
arch/x86/kernel/ptrace.c renamed from arch/x86/kernel/ptrace.c~memrlimit-controller-address-space-accounting-and-control +13 -5
@@ -20,6 +20,7 @@#include <linux/audit.h> #include <linux/seccomp.h> #include <linux/signal.h> +#include <linux/memrlimitcgroup.h> #include <asm/uaccess.h> #include <asm/pgtable.h>
@@ -782,21 +783,25 @@ static int ptrace_bts_realloc(struct tas current->mm->total_vm -= old_size; current->mm->locked_vm -= old_size; +memrlimit_cgroup_uncharge_as (mm, old_size);if (size ==0 ) goto out; +if (memrlimit_cgroup_charge_as (current->mm, size)) + goto out; + rlim = current->signal->rlim[RLIMIT_AS ].rlim_cur >>PAGE_SHIFT ; vm = current->mm->total_vm + size;if (rlim < vm) { ret = -ENOMEM ;if (!reduce_size) - goto out; + goto out_uncharge; size = rlim - current->mm->total_vm;if (size <=0 ) - goto out; + goto out_uncharge; } rlim = current->signal->rlim[RLIMIT_MEMLOCK ].rlim_cur >>PAGE_SHIFT ;
@@ -805,21 +810,24 @@ static int ptrace_bts_realloc(struct tas ret = -ENOMEM ;if (!reduce_size) - goto out; + goto out_uncharge; size = rlim - current->mm->locked_vm;if (size <=0 ) - goto out; + goto out_uncharge; } ret =ds_allocate ((void **)&child->thread.ds_area_msr, size <<PAGE_SHIFT );if (ret <0 ) - goto out; + goto out_uncharge; current->mm->total_vm += size; current->mm->locked_vm += size; +out_uncharge: +if (ret <0 ) +memrlimit_cgroup_uncharge_as (mm, size); out:if (child->thread.ds_area_msr)set_tsk_thread_flag (child,TIF_DS_AREA_MSR );
_
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 4/4] Add memrlimit controller accounting and control (v5)
On Wed, May 21, 2008 at 09:00:12PM +0530, Balbir Singh wrote:
[..]
Quoted 11 lines
mm/memrlimitcgroup.c renamed from mm/memrlimitcgroup.c~memrlimit-controller-address-space-accounting-and-control +11
-0+static void memrlimit_cgroup_move_task (struct cgroup_subsys *ss, +struct cgroup *cgrp, +struct cgroup *old_cgrp, +struct task_struct *p) +{ +struct mm_struct *mm; +struct memrlimit_cgroup *memrcg, *old_memrcg; + + mm =get_task_mm (p); +if (mm ==NULL ) +return ;
mm/memrlimitcgroup.c static int memrlimit_cgroup_populate(str · line 189
Quoted 10 lines
mm/memrlimitcgroup.c renamed from mm/memrlimitcgroup.c~memrlimit-controller-address-space-accounting-and-control +10
-0+ +/* +* Hold mmap_sem, so that total_vm does not change underneath us +*/ +down_read (&mm->mmap_sem); + +rcu_read_lock (); +if (p !=rcu_dereference (mm->owner)) + goto out; +
Hi Balbir,
How does rcu help here? We are not dereferencing mm->owner. So even if task_struct it was pointing to goes away, should not be a problem.
OTOH, while updating the mm->owner in mmm_update_next_owner(), we are not using rcu_assing_pointer() and synchronize_rcu()/call_rcu(). Is this the right usage if mm->owner is rcu protected?
Thanks
Vivek
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 4/4] Add memrlimit controller accounting and control (v5)
Quoted 27 lines · Vivek Goyal
On Wed, May 21, 2008 at 09:00:12PM +0530, Balbir Singh wrote:
[..]
Quoted 11 lines
mm/memrlimitcgroup.c renamed from mm/memrlimitcgroup.c~memrlimit-controller-address-space-accounting-and-control +11
-0+static void memrlimit_cgroup_move_task (struct cgroup_subsys *ss, +struct cgroup *cgrp, +struct cgroup *old_cgrp, +struct task_struct *p) +{ +struct mm_struct *mm; +struct memrlimit_cgroup *memrcg, *old_memrcg; + + mm =get_task_mm (p); +if (mm ==NULL ) +return ;mm/memrlimitcgroup.c static int memrlimit_cgroup_populate(str · line 189
Quoted 10 lines
mm/memrlimitcgroup.c renamed from mm/memrlimitcgroup.c~memrlimit-controller-address-space-accounting-and-control +10
-0+ +/* +* Hold mmap_sem, so that total_vm does not change underneath us +*/ +down_read (&mm->mmap_sem); + +rcu_read_lock (); +if (p !=rcu_dereference (mm->owner)) + goto out; +Hi Balbir,
Quoted 3 lines
How does rcu help here? We are not dereferencing
mm->owner. So even iftask_structit was pointing to goes away, should not be a problem.
Yes, you are right, since we already have information about the cgroup and new cgroup, mm->owner's exit should not really cause a problem
Quoted 4 lines
OTOH, while updating the
mm->ownerinmmm_update_next_owner(), we are not usingrcu_assing_pointer()and synchronize_rcu()/call_rcu(). Is this the right usage ifmm->owneris rcu protected?
Yes, you are correct - I'll send out updates on top of this one.
Quoted 8 lines
Thanks
Vivek--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [-mm][PATCH 4/4] Add memrlimit controller accounting and control (v5)
In reply to Balbir SinghQuoted 12 lines · On Wed, 21 May 2008 21:00:12 +0530 Balbir Singh <[email protected]>…
This patch adds support for accounting and control of virtual address space limits. The accounting is done via the rlimit_cgroup_(un)charge_as functions. The core of the accounting takes place during fork time in
copy_process(),may_expand_vm(),remove_vma_list()andexit_mmap().Changelog
v5->v4Move specific hooks in code to
insert_vm_struct
Usemmap_semto protectmm->ownerfrom changing andmm->ownerfrom changing cgroups.
Quoted 6 lines
...
+ *
brk(),sbrk()), stack expansion,mremap(), etc - called with
+ *mmap_semheld.
+ * decreasing - called withmmap_semheld.
+ * This callback is called withmmap_semheld
It's good to document the locking prerequisites but for rwsems, one should specify whether it must be held for reading or for writing.
Of course, down_write() is a superset of down_read(), so if it's "held for reading" then either mode-of-holding is OK. But it's best to spell all that out.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [-mm][PATCH 4/4] Add memrlimit controller accounting and control (v5)
Quoted 20 lines · Andrew Morton
Quoted 11 lines · On Wed, 21 May 2008 21:00:12 +0530 Balbir Singh <[email protected]>…
This patch adds support for accounting and control of virtual address space limits. The accounting is done via the rlimit_cgroup_(un)charge_as functions. The core of the accounting takes place during fork time in
copy_process(),may_expand_vm(),remove_vma_list()andexit_mmap().Changelog
v5->v4Move specific hooks in code to
insert_vm_struct
Usemmap_semto protectmm->ownerfrom changing andmm->ownerfrom changing cgroups.Quoted 6 lines
...
+ *
brk(),sbrk()), stack expansion,mremap(), etc - called with
+ *mmap_semheld.
+ * decreasing - called withmmap_semheld.
+ * This callback is called withmmap_semheld
Quoted 7 lines
It's good to document the locking prerequisites but for rwsems, one should specify whether it must be held for reading or for writing.
Of course,
down_write()is a superset ofdown_read(), so if it's "held for reading" then either mode-of-holding is OK. But it's best to spell all that out.
Sure, will do
Signature · 10 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>