[PATCH RESEND] mm/vmscan : use vmcan_swappiness( ) basing on MEMCG config to elimiate unnecessary runtime cost
Currently, we get the vm_swappiness via vmscan_swappiness(), which calls global_reclaim() to check if this is a global reclaim. Besides, the current implementation of global_reclaim() always returns true for the !CONFIG_MEGCG case, and judges the other case by checking whether scan_control->target_mem_cgroup is null or not. Thus, we could just use two versions of vmscan_swappiness() based on MEMCG Kconfig , to eliminate the unnecessary run-time cost for the !CONFIG_MEMCG at all, and to squash all memcg-related checking into the CONFIG_MEMCG version. Signed-off-by: Zhan Jianyu --- mm/memcontrol.c |6 +- mm/vmscan.c |9 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index c5792a5..1290320 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1525,9 +1525,13 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg) int mem_cgroup_swappiness(struct mem_cgroup *memcg) { - struct cgroup *cgrp = memcg->css.cgroup; + struct cgroup *cgrp; + + if (!memcg) + return vm_swappiness; /* root ? */ + cgrp = memcg->css.cgroup; if (cgrp->parent == NULL) return vm_swappiness; diff --git a/mm/vmscan.c b/mm/vmscan.c index 2cff0d4..1de652d 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1742,12 +1742,17 @@ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, return shrink_inactive_list(nr_to_scan, lruvec, sc, lru); } +#ifdef CONFIG_MEMCG static int vmscan_swappiness(struct scan_control *sc) { - if (global_reclaim(sc)) - return vm_swappiness; return mem_cgroup_swappiness(sc->target_mem_cgroup); } +#else +static int vmscan_swappiness(struct scan_control *sc) +{ + return vm_swappiness; +} +#endif enum scan_balance { SCAN_EQUAL, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Documentation/memory-barriers: fix a error that mistakes a CPU notion in Section Transitivity
The memory-barriers document may has a error in Section TRANSITIVITY. For transitivity, see a example below, given that * CPU 2's load from X follows CPU 1's store to X, and CPU 2's load from Y preceds CPU 3's store to Y. CPU 1 CPU 2 CPU 3 === === === { X = 0, Y = 0 } STORE X=1 LOAD X STORE Y=1 LOAD Y LOAD X The in CPU 2 is inadquate, because it could _only_ guarantees that load operation _happen before_ load operation after the barrier, with respect to CPU 3, which constrained by a general barrier, but provide _NO_ guarantee that CPU 1' store X will happen before the . Therefore, if this example runs on a system where CPUs 1 and 3 share a store buffer or a level of cache, CPU 3 might have early access to CPU 1's writes. The original text has mistaken CPU 2 for CPU 3, so this patch fixes this, and adds a paragraph to explain why a should guarantee this. Signed-off-by: Zhan Jianyu --- Documentation/memory-barriers.txt | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index fa5d8a9..590a5a9 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -992,6 +992,13 @@ transitivity. Therefore, in the above example, if CPU 2's load from X returns 1 and its load from Y returns 0, then CPU 3's load from X must also return 1. +The key point is that CPU 1's storing 1 to X preceds CPU 2's loading 1 +from X, and CPU 2's loading 0 from Y preceds CPU 3's storing 1 to Y, +which implies a ordering that the general barrier in CPU 2 guarantees: +all store and load operations must happen before those after the barrier +with respect to view of CPU 3, which constrained by a general barrier, too. +Thus, CPU 3's load from X must return 1. + However, transitivity is -not- guaranteed for read or write barriers. For example, suppose that CPU 2's general barrier in the above example is changed to a read barrier as shown below: @@ -1009,8 +1016,8 @@ and CPU 3's load from X to return 0. The key point is that although CPU 2's read barrier orders its pair of loads, it does not guarantee to order CPU 1's store. Therefore, if -this example runs on a system where CPUs 1 and 2 share a store buffer -or a level of cache, CPU 2 might have early access to CPU 1's writes. +this example runs on a system where CPUs 1 and 3 share a store buffer +or a level of cache, CPU 3 might have early access to CPU 1's writes. General barriers are therefore required to ensure that all CPUs agree on the combined order of CPU 1's and CPU 2's accesses. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] mm/vmscan : use vmcan_swappiness( ) basing on MEMCG config to elimiate unnecessary runtime cost
Currently, we get the vm_swappiness via vmscan_swappiness(), which calls global_reclaim() to check if this is a global reclaim. Besides, the current implementation of global_reclaim() always returns true for the !CONFIG_MEGCG case, and judges the other case by checking whether scan_control->target_mem_cgroup is null or not. Thus, we could just use two versions of vmscan_swappiness() based on MEMCG Kconfig , to eliminate the unnecessary run-time cost for the !CONFIG_MEMCG at all, and to squash all memcg-related checking into the CONFIG_MEMCG version. Signed-off-by: Zhan Jianyu --- mm/memcontrol.c |6 +- mm/vmscan.c |9 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index c5792a5..1290320 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1525,9 +1525,13 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg) int mem_cgroup_swappiness(struct mem_cgroup *memcg) { - struct cgroup *cgrp = memcg->css.cgroup; + struct cgroup *cgrp; + + if (!memcg) + return vm_swappiness; /* root ? */ + cgrp = memcg->css.cgroup; if (cgrp->parent == NULL) return vm_swappiness; diff --git a/mm/vmscan.c b/mm/vmscan.c index 2cff0d4..1de652d 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1742,12 +1742,17 @@ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, return shrink_inactive_list(nr_to_scan, lruvec, sc, lru); } +#ifdef CONFIG_MEMCG static int vmscan_swappiness(struct scan_control *sc) { - if (global_reclaim(sc)) - return vm_swappiness; return mem_cgroup_swappiness(sc->target_mem_cgroup); } +#else +static int vmscan_swappiness(struct scan_control *sc) +{ + return vm_swappiness; +} +#endif enum scan_balance { SCAN_EQUAL, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] mm/vmscan: make global_reclaim() inline
Though Gcc is likely to inline them, we should better explictly do it manually, and also, this serve to document this fact. Signed-off-by: Zhan Jianyu --- mm/vmscan.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 1de652d..1946d7d 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -135,12 +135,12 @@ static LIST_HEAD(shrinker_list); static DECLARE_RWSEM(shrinker_rwsem); #ifdef CONFIG_MEMCG -static bool global_reclaim(struct scan_control *sc) +static inline bool global_reclaim(struct scan_control *sc) { return !sc->target_mem_cgroup; } #else -static bool global_reclaim(struct scan_control *sc) +static inline bool global_reclaim(struct scan_control *sc) { return true; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/