Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1253466 > unrolled thread
| Started by | Johannes Weiner <hannes@cmpxchg.org> |
|---|---|
| First post | 2015-10-22 06:30 +0200 |
| Last post | 2015-10-29 19:00 +0100 |
| Articles | 20 on this page of 41 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH 0/8] mm: memcontrol: account socket memory in unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-22 06:30 +0200
[PATCH 1/8] mm: page_counter: let page_counter_try_charge() return bool Johannes Weiner <hannes@cmpxchg.org> - 2015-10-22 06:30 +0200
Re: [PATCH 1/8] mm: page_counter: let page_counter_try_charge() return bool Michal Hocko <mhocko@kernel.org> - 2015-10-23 13:40 +0200
[PATCH 6/8] mm: vmscan: simplify memcg vs. global shrinker invocation Johannes Weiner <hannes@cmpxchg.org> - 2015-10-22 06:30 +0200
Re: [PATCH 6/8] mm: vmscan: simplify memcg vs. global shrinker invocation Michal Hocko <mhocko@kernel.org> - 2015-10-23 15:30 +0200
[PATCH 4/8] mm: memcontrol: prepare for unified hierarchy socket accounting Johannes Weiner <hannes@cmpxchg.org> - 2015-10-22 06:30 +0200
Re: [PATCH 4/8] mm: memcontrol: prepare for unified hierarchy socket accounting Michal Hocko <mhocko@kernel.org> - 2015-10-23 14:40 +0200
[PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-22 06:30 +0200
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Vladimir Davydov <vdavydov@virtuozzo.com> - 2015-10-22 20:50 +0200
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Michal Hocko <mhocko@kernel.org> - 2015-10-23 15:30 +0200
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy David Miller <davem@davemloft.net> - 2015-10-23 15:50 +0200
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-26 18:00 +0100
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Michal Hocko <mhocko@kernel.org> - 2015-10-27 13:30 +0100
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy David Miller <davem@davemloft.net> - 2015-10-27 14:40 +0100
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-27 16:50 +0100
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Michal Hocko <mhocko@kernel.org> - 2015-10-27 17:20 +0100
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-27 17:50 +0100
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy David Miller <davem@davemloft.net> - 2015-10-28 01:30 +0100
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-28 04:10 +0100
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Michal Hocko <mhocko@kernel.org> - 2015-10-29 16:30 +0100
Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-29 17:20 +0100
[PATCH 2/8] mm: memcontrol: export root_mem_cgroup Johannes Weiner <hannes@cmpxchg.org> - 2015-10-22 06:30 +0200
Re: [PATCH 2/8] mm: memcontrol: export root_mem_cgroup Michal Hocko <mhocko@kernel.org> - 2015-10-23 13:40 +0200
[PATCH 7/8] mm: vmscan: report vmpressure at the level of reclaim activity Johannes Weiner <hannes@cmpxchg.org> - 2015-10-22 06:30 +0200
Re: [PATCH 7/8] mm: vmscan: report vmpressure at the level of reclaim activity Vladimir Davydov <vdavydov@virtuozzo.com> - 2015-10-22 20:50 +0200
Re: [PATCH 7/8] mm: vmscan: report vmpressure at the level of reclaim activity Michal Hocko <mhocko@kernel.org> - 2015-10-23 16:00 +0200
[PATCH 8/8] mm: memcontrol: hook up vmpressure to socket pressure Johannes Weiner <hannes@cmpxchg.org> - 2015-10-22 06:30 +0200
Re: [PATCH 8/8] mm: memcontrol: hook up vmpressure to socket pressure Vladimir Davydov <vdavydov@virtuozzo.com> - 2015-10-22 21:00 +0200
[PATCH 3/8] net: consolidate memcg socket buffer tracking and accounting Johannes Weiner <hannes@cmpxchg.org> - 2015-10-22 06:30 +0200
Re: [PATCH 3/8] net: consolidate memcg socket buffer tracking and accounting Vladimir Davydov <vdavydov@virtuozzo.com> - 2015-10-22 20:50 +0200
Re: [PATCH 3/8] net: consolidate memcg socket buffer tracking and accounting Johannes Weiner <hannes@cmpxchg.org> - 2015-10-22 21:20 +0200
Re: [PATCH 3/8] net: consolidate memcg socket buffer tracking and accounting Vladimir Davydov <vdavydov@virtuozzo.com> - 2015-10-23 15:50 +0200
Re: [PATCH 3/8] net: consolidate memcg socket buffer tracking and accounting Michal Hocko <mhocko@kernel.org> - 2015-10-23 14:40 +0200
Re: [PATCH 0/8] mm: memcontrol: account socket memory in unified hierarchy Vladimir Davydov <vdavydov@virtuozzo.com> - 2015-10-22 20:50 +0200
Re: [PATCH 0/8] mm: memcontrol: account socket memory in unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-26 18:30 +0100
Re: [PATCH 0/8] mm: memcontrol: account socket memory in unified hierarchy Vladimir Davydov <vdavydov@virtuozzo.com> - 2015-10-27 09:50 +0100
Re: [PATCH 0/8] mm: memcontrol: account socket memory in unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-27 17:10 +0100
Re: [PATCH 0/8] mm: memcontrol: account socket memory in unified hierarchy Vladimir Davydov <vdavydov@virtuozzo.com> - 2015-10-28 09:30 +0100
Re: [PATCH 0/8] mm: memcontrol: account socket memory in unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-28 20:00 +0100
Re: [PATCH 0/8] mm: memcontrol: account socket memory in unified hierarchy Vladimir Davydov <vdavydov@virtuozzo.com> - 2015-10-29 10:30 +0100
Re: [PATCH 0/8] mm: memcontrol: account socket memory in unified hierarchy Johannes Weiner <hannes@cmpxchg.org> - 2015-10-29 19:00 +0100
Page 1 of 3 [1] 2 3 Next page →
| From | Johannes Weiner <hannes@cmpxchg.org> |
|---|---|
| Date | 2015-10-22 06:30 +0200 |
| Subject | [PATCH 0/8] mm: memcontrol: account socket memory in unified hierarchy |
| Message-ID | <qmfFL-87d-1@gated-at.bofh.it> |
Hi, this series adds socket buffer memory tracking and accounting to the unified hierarchy memory cgroup controller. [ Networking people, at this time please check the diffstat below to avoid going into convulsions. ] Socket buffer memory can make up a significant share of a workload's memory footprint, and so it needs to be accounted and tracked out of the box, along with other types of memory that can be directly linked to userspace activity, in order to provide useful resource isolation. Historically, socket buffers were accounted in a separate counter, without any pressure equalization between anonymous memory, page cache, and the socket buffers. When the socket buffer pool was exhausted, buffer allocations would fail hard and cause network performance to tank, regardless of whether there was still memory available to the group or not. Likewise, struggling anonymous or cache workingsets could not dip into an idle socket memory pool. Because of this, the feature was not usable for many real life applications. To not repeat this mistake, the new memory controller will account all types of memory pages it is tracking on behalf of a cgroup in a single pool. And upon pressure, the VM reclaims and shrinks whatever memory in that pool is within its reach. These patches add accounting for memory consumed by sockets associated with a cgroup to the existing pool of anonymous pages and page cache. Patch #3 reworks the existing memcg socket infrastructure. It has many provisions for future plans that won't materialize, and much of this simply evaporates. The networking people should be happy about this. Patch #5 adds accounting and tracking of socket memory to the unified hierarchy memory controller, as described above. It uses the existing per-cpu charge caches and triggers high limit reclaim asynchroneously. Patch #8 uses the vmpressure extension to equalize pressure between the pages tracked natively by the VM and socket buffer pages. As the pool is shared, it makes sense that while natively tracked pages are under duress the network transmit windows are also not increased. As per above, this is an essential part of the new memory controller's core functionality. With the unified hierarchy nearing release, please consider this for 4.4. include/linux/memcontrol.h | 90 +++++++++------- include/linux/page_counter.h | 6 +- include/net/sock.h | 139 ++---------------------- include/net/tcp.h | 5 +- include/net/tcp_memcontrol.h | 7 -- mm/backing-dev.c | 2 +- mm/hugetlb_cgroup.c | 3 +- mm/memcontrol.c | 235 ++++++++++++++++++++++++++--------------- mm/page_counter.c | 14 +-- mm/vmpressure.c | 29 ++++- mm/vmscan.c | 41 +++---- net/core/sock.c | 78 ++++---------- net/ipv4/sysctl_net_ipv4.c | 1 - net/ipv4/tcp.c | 3 +- net/ipv4/tcp_ipv4.c | 9 +- net/ipv4/tcp_memcontrol.c | 147 ++++---------------------- net/ipv4/tcp_output.c | 6 +- net/ipv6/tcp_ipv6.c | 3 - 18 files changed, 319 insertions(+), 499 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Johannes Weiner <hannes@cmpxchg.org> |
|---|---|
| Date | 2015-10-22 06:30 +0200 |
| Subject | [PATCH 1/8] mm: page_counter: let page_counter_try_charge() return bool |
| Message-ID | <qmfFL-87d-3@gated-at.bofh.it> |
| In reply to | #1253466 |
page_counter_try_charge() currently returns 0 on success and -ENOMEM
on failure, which is surprising behavior given the function name.
Make it follow the expected pattern of try_stuff() functions that
return a boolean true to indicate success, or false for failure.
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
---
include/linux/page_counter.h | 6 +++---
mm/hugetlb_cgroup.c | 3 ++-
mm/memcontrol.c | 11 +++++------
mm/page_counter.c | 14 +++++++-------
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/include/linux/page_counter.h b/include/linux/page_counter.h
index 17fa4f8..7e62920 100644
--- a/include/linux/page_counter.h
+++ b/include/linux/page_counter.h
@@ -36,9 +36,9 @@ static inline unsigned long page_counter_read(struct page_counter *counter)
void page_counter_cancel(struct page_counter *counter, unsigned long nr_pages);
void page_counter_charge(struct page_counter *counter, unsigned long nr_pages);
-int page_counter_try_charge(struct page_counter *counter,
- unsigned long nr_pages,
- struct page_counter **fail);
+bool page_counter_try_charge(struct page_counter *counter,
+ unsigned long nr_pages,
+ struct page_counter **fail);
void page_counter_uncharge(struct page_counter *counter, unsigned long nr_pages);
int page_counter_limit(struct page_counter *counter, unsigned long limit);
int page_counter_memparse(const char *buf, const char *max,
diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c
index 6a44263..d8fb10d 100644
--- a/mm/hugetlb_cgroup.c
+++ b/mm/hugetlb_cgroup.c
@@ -186,7 +186,8 @@ again:
}
rcu_read_unlock();
- ret = page_counter_try_charge(&h_cg->hugepage[idx], nr_pages, &counter);
+ if (!page_counter_try_charge(&h_cg->hugepage[idx], nr_pages, &counter))
+ ret = -ENOMEM;
css_put(&h_cg->css);
done:
*ptr = h_cg;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index c71fe40..a8ccdbc 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2018,8 +2018,8 @@ retry:
return 0;
if (!do_swap_account ||
- !page_counter_try_charge(&memcg->memsw, batch, &counter)) {
- if (!page_counter_try_charge(&memcg->memory, batch, &counter))
+ page_counter_try_charge(&memcg->memsw, batch, &counter)) {
+ if (page_counter_try_charge(&memcg->memory, batch, &counter))
goto done_restock;
if (do_swap_account)
page_counter_uncharge(&memcg->memsw, batch);
@@ -2383,14 +2383,13 @@ int __memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order,
{
unsigned int nr_pages = 1 << order;
struct page_counter *counter;
- int ret = 0;
+ int ret;
if (!memcg_kmem_is_active(memcg))
return 0;
- ret = page_counter_try_charge(&memcg->kmem, nr_pages, &counter);
- if (ret)
- return ret;
+ if (!page_counter_try_charge(&memcg->kmem, nr_pages, &counter))
+ return -ENOMEM;
ret = try_charge(memcg, gfp, nr_pages);
if (ret) {
diff --git a/mm/page_counter.c b/mm/page_counter.c
index 11b4bed..7c6a63d 100644
--- a/mm/page_counter.c
+++ b/mm/page_counter.c
@@ -56,12 +56,12 @@ void page_counter_charge(struct page_counter *counter, unsigned long nr_pages)
* @nr_pages: number of pages to charge
* @fail: points first counter to hit its limit, if any
*
- * Returns 0 on success, or -ENOMEM and @fail if the counter or one of
- * its ancestors has hit its configured limit.
+ * Returns %true on success, or %false and @fail if the counter or one
+ * of its ancestors has hit its configured limit.
*/
-int page_counter_try_charge(struct page_counter *counter,
- unsigned long nr_pages,
- struct page_counter **fail)
+bool page_counter_try_charge(struct page_counter *counter,
+ unsigned long nr_pages,
+ struct page_counter **fail)
{
struct page_counter *c;
@@ -99,13 +99,13 @@ int page_counter_try_charge(struct page_counter *counter,
if (new > c->watermark)
c->watermark = new;
}
- return 0;
+ return true;
failed:
for (c = counter; c != *fail; c = c->parent)
page_counter_cancel(c, nr_pages);
- return -ENOMEM;
+ return false;
}
/**
--
2.6.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2015-10-23 13:40 +0200 |
| Subject | Re: [PATCH 1/8] mm: page_counter: let page_counter_try_charge() return bool |
| Message-ID | <qmIRt-9n-37@gated-at.bofh.it> |
| In reply to | #1253467 |
On Thu 22-10-15 00:21:29, Johannes Weiner wrote:
> page_counter_try_charge() currently returns 0 on success and -ENOMEM
> on failure, which is surprising behavior given the function name.
>
> Make it follow the expected pattern of try_stuff() functions that
> return a boolean true to indicate success, or false for failure.
>
> Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
> include/linux/page_counter.h | 6 +++---
> mm/hugetlb_cgroup.c | 3 ++-
> mm/memcontrol.c | 11 +++++------
> mm/page_counter.c | 14 +++++++-------
> 4 files changed, 17 insertions(+), 17 deletions(-)
>
> diff --git a/include/linux/page_counter.h b/include/linux/page_counter.h
> index 17fa4f8..7e62920 100644
> --- a/include/linux/page_counter.h
> +++ b/include/linux/page_counter.h
> @@ -36,9 +36,9 @@ static inline unsigned long page_counter_read(struct page_counter *counter)
>
> void page_counter_cancel(struct page_counter *counter, unsigned long nr_pages);
> void page_counter_charge(struct page_counter *counter, unsigned long nr_pages);
> -int page_counter_try_charge(struct page_counter *counter,
> - unsigned long nr_pages,
> - struct page_counter **fail);
> +bool page_counter_try_charge(struct page_counter *counter,
> + unsigned long nr_pages,
> + struct page_counter **fail);
> void page_counter_uncharge(struct page_counter *counter, unsigned long nr_pages);
> int page_counter_limit(struct page_counter *counter, unsigned long limit);
> int page_counter_memparse(const char *buf, const char *max,
> diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c
> index 6a44263..d8fb10d 100644
> --- a/mm/hugetlb_cgroup.c
> +++ b/mm/hugetlb_cgroup.c
> @@ -186,7 +186,8 @@ again:
> }
> rcu_read_unlock();
>
> - ret = page_counter_try_charge(&h_cg->hugepage[idx], nr_pages, &counter);
> + if (!page_counter_try_charge(&h_cg->hugepage[idx], nr_pages, &counter))
> + ret = -ENOMEM;
> css_put(&h_cg->css);
> done:
> *ptr = h_cg;
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index c71fe40..a8ccdbc 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -2018,8 +2018,8 @@ retry:
> return 0;
>
> if (!do_swap_account ||
> - !page_counter_try_charge(&memcg->memsw, batch, &counter)) {
> - if (!page_counter_try_charge(&memcg->memory, batch, &counter))
> + page_counter_try_charge(&memcg->memsw, batch, &counter)) {
> + if (page_counter_try_charge(&memcg->memory, batch, &counter))
> goto done_restock;
> if (do_swap_account)
> page_counter_uncharge(&memcg->memsw, batch);
> @@ -2383,14 +2383,13 @@ int __memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order,
> {
> unsigned int nr_pages = 1 << order;
> struct page_counter *counter;
> - int ret = 0;
> + int ret;
>
> if (!memcg_kmem_is_active(memcg))
> return 0;
>
> - ret = page_counter_try_charge(&memcg->kmem, nr_pages, &counter);
> - if (ret)
> - return ret;
> + if (!page_counter_try_charge(&memcg->kmem, nr_pages, &counter))
> + return -ENOMEM;
>
> ret = try_charge(memcg, gfp, nr_pages);
> if (ret) {
> diff --git a/mm/page_counter.c b/mm/page_counter.c
> index 11b4bed..7c6a63d 100644
> --- a/mm/page_counter.c
> +++ b/mm/page_counter.c
> @@ -56,12 +56,12 @@ void page_counter_charge(struct page_counter *counter, unsigned long nr_pages)
> * @nr_pages: number of pages to charge
> * @fail: points first counter to hit its limit, if any
> *
> - * Returns 0 on success, or -ENOMEM and @fail if the counter or one of
> - * its ancestors has hit its configured limit.
> + * Returns %true on success, or %false and @fail if the counter or one
> + * of its ancestors has hit its configured limit.
> */
> -int page_counter_try_charge(struct page_counter *counter,
> - unsigned long nr_pages,
> - struct page_counter **fail)
> +bool page_counter_try_charge(struct page_counter *counter,
> + unsigned long nr_pages,
> + struct page_counter **fail)
> {
> struct page_counter *c;
>
> @@ -99,13 +99,13 @@ int page_counter_try_charge(struct page_counter *counter,
> if (new > c->watermark)
> c->watermark = new;
> }
> - return 0;
> + return true;
>
> failed:
> for (c = counter; c != *fail; c = c->parent)
> page_counter_cancel(c, nr_pages);
>
> - return -ENOMEM;
> + return false;
> }
>
> /**
> --
> 2.6.1
--
Michal Hocko
SUSE Labs
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Johannes Weiner <hannes@cmpxchg.org> |
|---|---|
| Date | 2015-10-22 06:30 +0200 |
| Subject | [PATCH 6/8] mm: vmscan: simplify memcg vs. global shrinker invocation |
| Message-ID | <qmfFL-87d-5@gated-at.bofh.it> |
| In reply to | #1253466 |
Letting shrink_slab() handle the root_mem_cgroup, and implicitely the
!CONFIG_MEMCG case, allows shrink_zone() to invoke the shrinkers
unconditionally from within the memcg iteration loop.
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
---
include/linux/memcontrol.h | 2 ++
mm/vmscan.c | 31 ++++++++++++++++---------------
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 6f1e0f8..d66ae18 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -482,6 +482,8 @@ void mem_cgroup_split_huge_fixup(struct page *head);
#else /* CONFIG_MEMCG */
struct mem_cgroup;
+#define root_mem_cgroup NULL
+
static inline void mem_cgroup_events(struct mem_cgroup *memcg,
enum mem_cgroup_events_index idx,
unsigned int nr)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 9b52ecf..ecc2125 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -411,6 +411,10 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
struct shrinker *shrinker;
unsigned long freed = 0;
+ /* Global shrinker mode */
+ if (memcg == root_mem_cgroup)
+ memcg = NULL;
+
if (memcg && !memcg_kmem_is_active(memcg))
return 0;
@@ -2417,11 +2421,22 @@ static bool shrink_zone(struct zone *zone, struct scan_control *sc,
shrink_lruvec(lruvec, swappiness, sc, &lru_pages);
zone_lru_pages += lru_pages;
- if (memcg && is_classzone)
+ /*
+ * Shrink the slab caches in the same proportion that
+ * the eligible LRU pages were scanned.
+ */
+ if (is_classzone) {
shrink_slab(sc->gfp_mask, zone_to_nid(zone),
memcg, sc->nr_scanned - scanned,
lru_pages);
+ if (reclaim_state) {
+ sc->nr_reclaimed +=
+ reclaim_state->reclaimed_slab;
+ reclaim_state->reclaimed_slab = 0;
+ }
+ }
+
/*
* Direct reclaim and kswapd have to scan all memory
* cgroups to fulfill the overall scan target for the
@@ -2439,20 +2454,6 @@ static bool shrink_zone(struct zone *zone, struct scan_control *sc,
}
} while ((memcg = mem_cgroup_iter(root, memcg, &reclaim)));
- /*
- * Shrink the slab caches in the same proportion that
- * the eligible LRU pages were scanned.
- */
- if (global_reclaim(sc) && is_classzone)
- shrink_slab(sc->gfp_mask, zone_to_nid(zone), NULL,
- sc->nr_scanned - nr_scanned,
- zone_lru_pages);
-
- if (reclaim_state) {
- sc->nr_reclaimed += reclaim_state->reclaimed_slab;
- reclaim_state->reclaimed_slab = 0;
- }
-
vmpressure(sc->gfp_mask, sc->target_mem_cgroup,
sc->nr_scanned - nr_scanned,
sc->nr_reclaimed - nr_reclaimed);
--
2.6.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2015-10-23 15:30 +0200 |
| Subject | Re: [PATCH 6/8] mm: vmscan: simplify memcg vs. global shrinker invocation |
| Message-ID | <qmKzU-2Fk-5@gated-at.bofh.it> |
| In reply to | #1253468 |
On Thu 22-10-15 00:21:34, Johannes Weiner wrote:
> Letting shrink_slab() handle the root_mem_cgroup, and implicitely the
> !CONFIG_MEMCG case, allows shrink_zone() to invoke the shrinkers
> unconditionally from within the memcg iteration loop.
>
> Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
> include/linux/memcontrol.h | 2 ++
> mm/vmscan.c | 31 ++++++++++++++++---------------
> 2 files changed, 18 insertions(+), 15 deletions(-)
>
> diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> index 6f1e0f8..d66ae18 100644
> --- a/include/linux/memcontrol.h
> +++ b/include/linux/memcontrol.h
> @@ -482,6 +482,8 @@ void mem_cgroup_split_huge_fixup(struct page *head);
> #else /* CONFIG_MEMCG */
> struct mem_cgroup;
>
> +#define root_mem_cgroup NULL
> +
> static inline void mem_cgroup_events(struct mem_cgroup *memcg,
> enum mem_cgroup_events_index idx,
> unsigned int nr)
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 9b52ecf..ecc2125 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -411,6 +411,10 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
> struct shrinker *shrinker;
> unsigned long freed = 0;
>
> + /* Global shrinker mode */
> + if (memcg == root_mem_cgroup)
> + memcg = NULL;
> +
> if (memcg && !memcg_kmem_is_active(memcg))
> return 0;
>
> @@ -2417,11 +2421,22 @@ static bool shrink_zone(struct zone *zone, struct scan_control *sc,
> shrink_lruvec(lruvec, swappiness, sc, &lru_pages);
> zone_lru_pages += lru_pages;
>
> - if (memcg && is_classzone)
> + /*
> + * Shrink the slab caches in the same proportion that
> + * the eligible LRU pages were scanned.
> + */
> + if (is_classzone) {
> shrink_slab(sc->gfp_mask, zone_to_nid(zone),
> memcg, sc->nr_scanned - scanned,
> lru_pages);
>
> + if (reclaim_state) {
> + sc->nr_reclaimed +=
> + reclaim_state->reclaimed_slab;
> + reclaim_state->reclaimed_slab = 0;
> + }
> + }
> +
> /*
> * Direct reclaim and kswapd have to scan all memory
> * cgroups to fulfill the overall scan target for the
> @@ -2439,20 +2454,6 @@ static bool shrink_zone(struct zone *zone, struct scan_control *sc,
> }
> } while ((memcg = mem_cgroup_iter(root, memcg, &reclaim)));
>
> - /*
> - * Shrink the slab caches in the same proportion that
> - * the eligible LRU pages were scanned.
> - */
> - if (global_reclaim(sc) && is_classzone)
> - shrink_slab(sc->gfp_mask, zone_to_nid(zone), NULL,
> - sc->nr_scanned - nr_scanned,
> - zone_lru_pages);
> -
> - if (reclaim_state) {
> - sc->nr_reclaimed += reclaim_state->reclaimed_slab;
> - reclaim_state->reclaimed_slab = 0;
> - }
> -
> vmpressure(sc->gfp_mask, sc->target_mem_cgroup,
> sc->nr_scanned - nr_scanned,
> sc->nr_reclaimed - nr_reclaimed);
> --
> 2.6.1
--
Michal Hocko
SUSE Labs
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Johannes Weiner <hannes@cmpxchg.org> |
|---|---|
| Date | 2015-10-22 06:30 +0200 |
| Subject | [PATCH 4/8] mm: memcontrol: prepare for unified hierarchy socket accounting |
| Message-ID | <qmfFL-87d-7@gated-at.bofh.it> |
| In reply to | #1253466 |
The unified hierarchy memory controller will account socket
memory. Move the infrastructure functions accordingly.
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
---
mm/memcontrol.c | 136 ++++++++++++++++++++++++++++----------------------------
1 file changed, 68 insertions(+), 68 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index c41e6d7..3789050 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -287,74 +287,6 @@ static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
return mem_cgroup_from_css(css);
}
-/* Writing them here to avoid exposing memcg's inner layout */
-#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
-
-DEFINE_STATIC_KEY_FALSE(mem_cgroup_sockets);
-
-void sock_update_memcg(struct sock *sk)
-{
- struct mem_cgroup *memcg;
- /*
- * Socket cloning can throw us here with sk_cgrp already
- * filled. It won't however, necessarily happen from
- * process context. So the test for root memcg given
- * the current task's memcg won't help us in this case.
- *
- * Respecting the original socket's memcg is a better
- * decision in this case.
- */
- if (sk->sk_memcg) {
- BUG_ON(mem_cgroup_is_root(sk->sk_memcg));
- css_get(&sk->sk_memcg->css);
- return;
- }
-
- rcu_read_lock();
- memcg = mem_cgroup_from_task(current);
- if (css_tryget_online(&memcg->css))
- sk->sk_memcg = memcg;
- rcu_read_unlock();
-}
-EXPORT_SYMBOL(sock_update_memcg);
-
-void sock_release_memcg(struct sock *sk)
-{
- if (sk->sk_memcg)
- css_put(&sk->sk_memcg->css);
-}
-
-/**
- * mem_cgroup_charge_skmem - charge socket memory
- * @memcg: memcg to charge
- * @nr_pages: number of pages to charge
- *
- * Charges @nr_pages to @memcg. Returns %true if the charge fit within
- * the memcg's configured limit, %false if the charge had to be forced.
- */
-bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
-{
- struct page_counter *counter;
-
- if (page_counter_try_charge(&memcg->skmem, nr_pages, &counter))
- return true;
-
- page_counter_charge(&memcg->skmem, nr_pages);
- return false;
-}
-
-/**
- * mem_cgroup_uncharge_skmem - uncharge socket memory
- * @memcg: memcg to uncharge
- * @nr_pages: number of pages to uncharge
- */
-void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
-{
- page_counter_uncharge(&memcg->skmem, nr_pages);
-}
-
-#endif
-
#ifdef CONFIG_MEMCG_KMEM
/*
* This will be the memcg's index in each cache's ->memcg_params.memcg_caches.
@@ -5521,6 +5453,74 @@ void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage)
commit_charge(newpage, memcg, true);
}
+/* Writing them here to avoid exposing memcg's inner layout */
+#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
+
+DEFINE_STATIC_KEY_FALSE(mem_cgroup_sockets);
+
+void sock_update_memcg(struct sock *sk)
+{
+ struct mem_cgroup *memcg;
+ /*
+ * Socket cloning can throw us here with sk_cgrp already
+ * filled. It won't however, necessarily happen from
+ * process context. So the test for root memcg given
+ * the current task's memcg won't help us in this case.
+ *
+ * Respecting the original socket's memcg is a better
+ * decision in this case.
+ */
+ if (sk->sk_memcg) {
+ BUG_ON(mem_cgroup_is_root(sk->sk_memcg));
+ css_get(&sk->sk_memcg->css);
+ return;
+ }
+
+ rcu_read_lock();
+ memcg = mem_cgroup_from_task(current);
+ if (css_tryget_online(&memcg->css))
+ sk->sk_memcg = memcg;
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL(sock_update_memcg);
+
+void sock_release_memcg(struct sock *sk)
+{
+ if (sk->sk_memcg)
+ css_put(&sk->sk_memcg->css);
+}
+
+/**
+ * mem_cgroup_charge_skmem - charge socket memory
+ * @memcg: memcg to charge
+ * @nr_pages: number of pages to charge
+ *
+ * Charges @nr_pages to @memcg. Returns %true if the charge fit within
+ * the memcg's configured limit, %false if the charge had to be forced.
+ */
+bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
+{
+ struct page_counter *counter;
+
+ if (page_counter_try_charge(&memcg->skmem, nr_pages, &counter))
+ return true;
+
+ page_counter_charge(&memcg->skmem, nr_pages);
+ return false;
+}
+
+/**
+ * mem_cgroup_uncharge_skmem - uncharge socket memory
+ * @memcg: memcg to uncharge
+ * @nr_pages: number of pages to uncharge
+ */
+void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
+{
+ page_counter_uncharge(&memcg->skmem, nr_pages);
+}
+
+#endif
+
/*
* subsys_initcall() for memory controller.
*
--
2.6.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2015-10-23 14:40 +0200 |
| Subject | Re: [PATCH 4/8] mm: memcontrol: prepare for unified hierarchy socket accounting |
| Message-ID | <qmJNw-1va-7@gated-at.bofh.it> |
| In reply to | #1253469 |
On Thu 22-10-15 00:21:32, Johannes Weiner wrote:
> The unified hierarchy memory controller will account socket
> memory. Move the infrastructure functions accordingly.
>
> Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
> mm/memcontrol.c | 136 ++++++++++++++++++++++++++++----------------------------
> 1 file changed, 68 insertions(+), 68 deletions(-)
>
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index c41e6d7..3789050 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -287,74 +287,6 @@ static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
> return mem_cgroup_from_css(css);
> }
>
> -/* Writing them here to avoid exposing memcg's inner layout */
> -#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
> -
> -DEFINE_STATIC_KEY_FALSE(mem_cgroup_sockets);
> -
> -void sock_update_memcg(struct sock *sk)
> -{
> - struct mem_cgroup *memcg;
> - /*
> - * Socket cloning can throw us here with sk_cgrp already
> - * filled. It won't however, necessarily happen from
> - * process context. So the test for root memcg given
> - * the current task's memcg won't help us in this case.
> - *
> - * Respecting the original socket's memcg is a better
> - * decision in this case.
> - */
> - if (sk->sk_memcg) {
> - BUG_ON(mem_cgroup_is_root(sk->sk_memcg));
> - css_get(&sk->sk_memcg->css);
> - return;
> - }
> -
> - rcu_read_lock();
> - memcg = mem_cgroup_from_task(current);
> - if (css_tryget_online(&memcg->css))
> - sk->sk_memcg = memcg;
> - rcu_read_unlock();
> -}
> -EXPORT_SYMBOL(sock_update_memcg);
> -
> -void sock_release_memcg(struct sock *sk)
> -{
> - if (sk->sk_memcg)
> - css_put(&sk->sk_memcg->css);
> -}
> -
> -/**
> - * mem_cgroup_charge_skmem - charge socket memory
> - * @memcg: memcg to charge
> - * @nr_pages: number of pages to charge
> - *
> - * Charges @nr_pages to @memcg. Returns %true if the charge fit within
> - * the memcg's configured limit, %false if the charge had to be forced.
> - */
> -bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
> -{
> - struct page_counter *counter;
> -
> - if (page_counter_try_charge(&memcg->skmem, nr_pages, &counter))
> - return true;
> -
> - page_counter_charge(&memcg->skmem, nr_pages);
> - return false;
> -}
> -
> -/**
> - * mem_cgroup_uncharge_skmem - uncharge socket memory
> - * @memcg: memcg to uncharge
> - * @nr_pages: number of pages to uncharge
> - */
> -void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
> -{
> - page_counter_uncharge(&memcg->skmem, nr_pages);
> -}
> -
> -#endif
> -
> #ifdef CONFIG_MEMCG_KMEM
> /*
> * This will be the memcg's index in each cache's ->memcg_params.memcg_caches.
> @@ -5521,6 +5453,74 @@ void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage)
> commit_charge(newpage, memcg, true);
> }
>
> +/* Writing them here to avoid exposing memcg's inner layout */
> +#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
> +
> +DEFINE_STATIC_KEY_FALSE(mem_cgroup_sockets);
> +
> +void sock_update_memcg(struct sock *sk)
> +{
> + struct mem_cgroup *memcg;
> + /*
> + * Socket cloning can throw us here with sk_cgrp already
> + * filled. It won't however, necessarily happen from
> + * process context. So the test for root memcg given
> + * the current task's memcg won't help us in this case.
> + *
> + * Respecting the original socket's memcg is a better
> + * decision in this case.
> + */
> + if (sk->sk_memcg) {
> + BUG_ON(mem_cgroup_is_root(sk->sk_memcg));
> + css_get(&sk->sk_memcg->css);
> + return;
> + }
> +
> + rcu_read_lock();
> + memcg = mem_cgroup_from_task(current);
> + if (css_tryget_online(&memcg->css))
> + sk->sk_memcg = memcg;
> + rcu_read_unlock();
> +}
> +EXPORT_SYMBOL(sock_update_memcg);
> +
> +void sock_release_memcg(struct sock *sk)
> +{
> + if (sk->sk_memcg)
> + css_put(&sk->sk_memcg->css);
> +}
> +
> +/**
> + * mem_cgroup_charge_skmem - charge socket memory
> + * @memcg: memcg to charge
> + * @nr_pages: number of pages to charge
> + *
> + * Charges @nr_pages to @memcg. Returns %true if the charge fit within
> + * the memcg's configured limit, %false if the charge had to be forced.
> + */
> +bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
> +{
> + struct page_counter *counter;
> +
> + if (page_counter_try_charge(&memcg->skmem, nr_pages, &counter))
> + return true;
> +
> + page_counter_charge(&memcg->skmem, nr_pages);
> + return false;
> +}
> +
> +/**
> + * mem_cgroup_uncharge_skmem - uncharge socket memory
> + * @memcg: memcg to uncharge
> + * @nr_pages: number of pages to uncharge
> + */
> +void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
> +{
> + page_counter_uncharge(&memcg->skmem, nr_pages);
> +}
> +
> +#endif
> +
> /*
> * subsys_initcall() for memory controller.
> *
> --
> 2.6.1
--
Michal Hocko
SUSE Labs
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Johannes Weiner <hannes@cmpxchg.org> |
|---|---|
| Date | 2015-10-22 06:30 +0200 |
| Subject | [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qmfFL-87d-9@gated-at.bofh.it> |
| In reply to | #1253466 |
Socket memory can be a significant share of overall memory consumed by
common workloads. In order to provide reasonable resource isolation
out-of-the-box in the unified hierarchy, this type of memory needs to
be accounted and tracked per default in the memory controller.
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
---
include/linux/memcontrol.h | 16 ++++++--
mm/memcontrol.c | 95 ++++++++++++++++++++++++++++++++++++----------
2 files changed, 87 insertions(+), 24 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 5b72f83..6f1e0f8 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -244,6 +244,10 @@ struct mem_cgroup {
struct wb_domain cgwb_domain;
#endif
+#ifdef CONFIG_INET
+ struct work_struct socket_work;
+#endif
+
/* List of events which userspace want to receive */
struct list_head event_list;
spinlock_t event_list_lock;
@@ -676,11 +680,15 @@ static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb,
#endif /* CONFIG_CGROUP_WRITEBACK */
struct sock;
-#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
-extern struct static_key_false mem_cgroup_sockets;
+#ifdef CONFIG_INET
+extern struct static_key_true mem_cgroup_sockets;
static inline bool mem_cgroup_do_sockets(void)
{
- return static_branch_unlikely(&mem_cgroup_sockets);
+ if (mem_cgroup_disabled())
+ return false;
+ if (!static_branch_likely(&mem_cgroup_sockets))
+ return false;
+ return true;
}
void sock_update_memcg(struct sock *sk);
void sock_release_memcg(struct sock *sk);
@@ -706,7 +714,7 @@ static inline void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg,
unsigned int nr_pages)
{
}
-#endif /* CONFIG_INET && CONFIG_MEMCG_KMEM */
+#endif /* CONFIG_INET */
#ifdef CONFIG_MEMCG_KMEM
extern struct static_key memcg_kmem_enabled_key;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3789050..cb1d6aa 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1916,6 +1916,18 @@ static int memcg_cpu_hotplug_callback(struct notifier_block *nb,
return NOTIFY_OK;
}
+static void reclaim_high(struct mem_cgroup *memcg,
+ unsigned int nr_pages,
+ gfp_t gfp_mask)
+{
+ do {
+ if (page_counter_read(&memcg->memory) <= memcg->high)
+ continue;
+ mem_cgroup_events(memcg, MEMCG_HIGH, 1);
+ try_to_free_mem_cgroup_pages(memcg, nr_pages, gfp_mask, true);
+ } while ((memcg = parent_mem_cgroup(memcg)));
+}
+
/*
* Scheduled by try_charge() to be executed from the userland return path
* and reclaims memory over the high limit.
@@ -1923,20 +1935,13 @@ static int memcg_cpu_hotplug_callback(struct notifier_block *nb,
void mem_cgroup_handle_over_high(void)
{
unsigned int nr_pages = current->memcg_nr_pages_over_high;
- struct mem_cgroup *memcg, *pos;
+ struct mem_cgroup *memcg;
if (likely(!nr_pages))
return;
- pos = memcg = get_mem_cgroup_from_mm(current->mm);
-
- do {
- if (page_counter_read(&pos->memory) <= pos->high)
- continue;
- mem_cgroup_events(pos, MEMCG_HIGH, 1);
- try_to_free_mem_cgroup_pages(pos, nr_pages, GFP_KERNEL, true);
- } while ((pos = parent_mem_cgroup(pos)));
-
+ memcg = get_mem_cgroup_from_mm(current->mm);
+ reclaim_high(memcg, nr_pages, GFP_KERNEL);
css_put(&memcg->css);
current->memcg_nr_pages_over_high = 0;
}
@@ -4129,6 +4134,8 @@ struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg)
}
EXPORT_SYMBOL(parent_mem_cgroup);
+static void socket_work_func(struct work_struct *work);
+
static struct cgroup_subsys_state * __ref
mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
{
@@ -4169,6 +4176,9 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
#ifdef CONFIG_CGROUP_WRITEBACK
INIT_LIST_HEAD(&memcg->cgwb_list);
#endif
+#ifdef CONFIG_INET
+ INIT_WORK(&memcg->socket_work, socket_work_func);
+#endif
return &memcg->css;
free_out:
@@ -4266,6 +4276,8 @@ static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
{
struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+ cancel_work_sync(&memcg->socket_work);
+
memcg_destroy_kmem(memcg);
__mem_cgroup_free(memcg);
}
@@ -4948,10 +4960,15 @@ static void mem_cgroup_bind(struct cgroup_subsys_state *root_css)
* guarantees that @root doesn't have any children, so turning it
* on for the root memcg is enough.
*/
- if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
+ if (cgroup_subsys_on_dfl(memory_cgrp_subsys)) {
root_mem_cgroup->use_hierarchy = true;
- else
+#ifdef CONFIG_INET
+ /* unified hierarchy always counts skmem */
+ static_branch_enable(&mem_cgroup_sockets);
+#endif
+ } else {
root_mem_cgroup->use_hierarchy = false;
+ }
}
static u64 memory_current_read(struct cgroup_subsys_state *css,
@@ -5453,10 +5470,9 @@ void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage)
commit_charge(newpage, memcg, true);
}
-/* Writing them here to avoid exposing memcg's inner layout */
-#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
+#ifdef CONFIG_INET
-DEFINE_STATIC_KEY_FALSE(mem_cgroup_sockets);
+DEFINE_STATIC_KEY_TRUE(mem_cgroup_sockets);
void sock_update_memcg(struct sock *sk)
{
@@ -5490,6 +5506,14 @@ void sock_release_memcg(struct sock *sk)
css_put(&sk->sk_memcg->css);
}
+static void socket_work_func(struct work_struct *work)
+{
+ struct mem_cgroup *memcg;
+
+ memcg = container_of(work, struct mem_cgroup, socket_work);
+ reclaim_high(memcg, CHARGE_BATCH, GFP_KERNEL);
+}
+
/**
* mem_cgroup_charge_skmem - charge socket memory
* @memcg: memcg to charge
@@ -5500,13 +5524,38 @@ void sock_release_memcg(struct sock *sk)
*/
bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
{
+ unsigned int batch = max(CHARGE_BATCH, nr_pages);
struct page_counter *counter;
+ bool force = false;
- if (page_counter_try_charge(&memcg->skmem, nr_pages, &counter))
+ if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) {
+ if (page_counter_try_charge(&memcg->skmem, nr_pages, &counter))
+ return true;
+ page_counter_charge(&memcg->skmem, nr_pages);
+ return false;
+ }
+
+ if (consume_stock(memcg, nr_pages))
return true;
+retry:
+ if (page_counter_try_charge(&memcg->memory, batch, &counter))
+ goto done;
- page_counter_charge(&memcg->skmem, nr_pages);
- return false;
+ if (batch > nr_pages) {
+ batch = nr_pages;
+ goto retry;
+ }
+
+ force = true;
+ page_counter_charge(&memcg->memory, batch);
+done:
+ css_get_many(&memcg->css, batch);
+ if (batch > nr_pages)
+ refill_stock(memcg, batch - nr_pages);
+
+ schedule_work(&memcg->socket_work);
+
+ return !force;
}
/**
@@ -5516,10 +5565,16 @@ bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
*/
void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
{
- page_counter_uncharge(&memcg->skmem, nr_pages);
+ if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) {
+ page_counter_uncharge(&memcg->skmem, nr_pages);
+ return;
+ }
+
+ page_counter_uncharge(&memcg->memory, nr_pages);
+ css_put_many(&memcg->css, nr_pages);
}
-#endif
+#endif /* CONFIG_INET */
/*
* subsys_initcall() for memory controller.
--
2.6.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Vladimir Davydov <vdavydov@virtuozzo.com> |
|---|---|
| Date | 2015-10-22 20:50 +0200 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qmt62-2wa-31@gated-at.bofh.it> |
| In reply to | #1253470 |
On Thu, Oct 22, 2015 at 12:21:33AM -0400, Johannes Weiner wrote:
...
> @@ -5500,13 +5524,38 @@ void sock_release_memcg(struct sock *sk)
> */
> bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
> {
> + unsigned int batch = max(CHARGE_BATCH, nr_pages);
> struct page_counter *counter;
> + bool force = false;
>
> - if (page_counter_try_charge(&memcg->skmem, nr_pages, &counter))
> + if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) {
> + if (page_counter_try_charge(&memcg->skmem, nr_pages, &counter))
> + return true;
> + page_counter_charge(&memcg->skmem, nr_pages);
> + return false;
> + }
> +
> + if (consume_stock(memcg, nr_pages))
> return true;
> +retry:
> + if (page_counter_try_charge(&memcg->memory, batch, &counter))
> + goto done;
Currently, we use memcg->memory only for charging memory pages. Besides,
every page charged to this counter (including kmem) has ->mem_cgroup
field set appropriately. This looks consistent and nice. As an extra
benefit, we can track all pages charged to a memory cgroup via
/proc/kapgecgroup.
Now, you charge "window size" to it, which AFAIU isn't necessarily equal
to the amount of memory actually consumed by the cgroup for socket
buffers. I think this looks ugly and inconsistent with the existing
behavior. I agree that we need to charge socker buffers to ->memory, but
IMO we should do that per each skb page, using memcg_kmem_charge_kmem
somewhere in alloc_skb_with_frags invoking the reclaimer just as we do
for kmalloc, while tcp window size control should stay aside.
Thanks,
Vladimir
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2015-10-23 15:30 +0200 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qmKzU-2Fk-13@gated-at.bofh.it> |
| In reply to | #1253470 |
On Thu 22-10-15 00:21:33, Johannes Weiner wrote:
> Socket memory can be a significant share of overall memory consumed by
> common workloads. In order to provide reasonable resource isolation
> out-of-the-box in the unified hierarchy, this type of memory needs to
> be accounted and tracked per default in the memory controller.
What about users who do not want to pay an additional overhead for the
accounting? How can they disable it?
> Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
[...]
> @@ -5453,10 +5470,9 @@ void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage)
> commit_charge(newpage, memcg, true);
> }
>
> -/* Writing them here to avoid exposing memcg's inner layout */
> -#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
> +#ifdef CONFIG_INET
>
> -DEFINE_STATIC_KEY_FALSE(mem_cgroup_sockets);
> +DEFINE_STATIC_KEY_TRUE(mem_cgroup_sockets);
AFAIU this means that the jump label is enabled by default. Is this
intended when you enable it explicitly where needed?
>
> void sock_update_memcg(struct sock *sk)
> {
--
Michal Hocko
SUSE Labs
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Miller <davem@davemloft.net> |
|---|---|
| Date | 2015-10-23 15:50 +0200 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qmKTh-32t-23@gated-at.bofh.it> |
| In reply to | #1254598 |
From: Michal Hocko <mhocko@kernel.org> Date: Fri, 23 Oct 2015 15:19:56 +0200 > On Thu 22-10-15 00:21:33, Johannes Weiner wrote: >> Socket memory can be a significant share of overall memory consumed by >> common workloads. In order to provide reasonable resource isolation >> out-of-the-box in the unified hierarchy, this type of memory needs to >> be accounted and tracked per default in the memory controller. > > What about users who do not want to pay an additional overhead for the > accounting? How can they disable it? Yeah, this really cannot pass. This extra overhead will be seen by %99.9999 of users, since entities (especially distributions) just flip on all of these config options by default. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Johannes Weiner <hannes@cmpxchg.org> |
|---|---|
| Date | 2015-10-26 18:00 +0100 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qnThM-2d0-17@gated-at.bofh.it> |
| In reply to | #1254616 |
On Fri, Oct 23, 2015 at 06:59:57AM -0700, David Miller wrote: > From: Michal Hocko <mhocko@kernel.org> > Date: Fri, 23 Oct 2015 15:19:56 +0200 > > > On Thu 22-10-15 00:21:33, Johannes Weiner wrote: > >> Socket memory can be a significant share of overall memory consumed by > >> common workloads. In order to provide reasonable resource isolation > >> out-of-the-box in the unified hierarchy, this type of memory needs to > >> be accounted and tracked per default in the memory controller. > > > > What about users who do not want to pay an additional overhead for the > > accounting? How can they disable it? > > Yeah, this really cannot pass. > > This extra overhead will be seen by %99.9999 of users, since entities > (especially distributions) just flip on all of these config options by > default. Okay, there are several layers to this issue. If you boot a machine with a CONFIG_MEMCG distribution kernel and don't create any cgroups, I agree there shouldn't be any overhead. I already sent a patch to generally remove memory accounting on the system or root level. I can easily update this patch here to not have any socket buffer accounting overhead for systems that don't actively use cgroups. Would you be okay with a branch on sk->sk_memcg in the network accounting path? I'd leave that NULL on the system level then. Then there is of course the case when you create cgroups for process organization but don't care about memory accounting. Systemd comes to mind. Or even if you create cgroups to track other resources like CPU but don't care about memory. The unified hierarchy no longer enables controllers on new cgroups per default, so unless you create a cgroup and specifically tell it to account and track memory, you won't have the socket memory accounting overhead, either. Then there is the third case, where you create a control group to specifically manage and limit the memory consumption of a workload. In that scenario, a major memory consumer like socket buffers, which can easily grow until OOM, should definitely be included in the tracking in order to properly contain both untrusted (possibly malicious) and trusted (possibly buggy) workloads. This is not a hole we can reasonbly leave unpatched for general purpose resource management. Now you could argue that there might exist specialized workloads that need to account anonymous pages and page cache, but not socket memory buffers. Or any other combination of pick-and-choose consumers. But honestly, nowadays all our paths are lockless, and the counting is an atomic-add-return with a per-cpu batch cache. I don't think there is a compelling case for an elaborate interface to make individual memory consumers configurable inside the memory controller. So in summary, would you be okay with this patch if networking only called into the memory controller when you explicitely create a cgroup AND tell it to track the memory footprint of the workload in it? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2015-10-27 13:30 +0100 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qoby2-59v-11@gated-at.bofh.it> |
| In reply to | #1256160 |
On Mon 26-10-15 12:56:19, Johannes Weiner wrote: [...] > Now you could argue that there might exist specialized workloads that > need to account anonymous pages and page cache, but not socket memory > buffers. Exactly, and there are loads doing this. Memcg groups are also created to limit anon/page cache consumers to not affect the others running on the system (basically in the root memcg context from memcg POV) which don't care about tracking and they definitely do not want to pay for an additional overhead. We should definitely be able to offer a global disable knob for them. The same applies to kmem accounting in general. I do understand with having the accounting enabled by default after we are reasonably sure that both kmem/tcp are stable enough (which I am not convinced about yet to be honest) but there will be always special loads which simply do not care about kmem/tcp accounting and rather pay a global balancing price (even OOM) rather than a permanent price. And they should get a way to opt-out. > Or any other combination of pick-and-choose consumers. But > honestly, nowadays all our paths are lockless, and the counting is an > atomic-add-return with a per-cpu batch cache. You are still hooking into hot paths and there are users who want to squeeze every single cycle from the HW. > I don't think there is a compelling case for an elaborate interface > to make individual memory consumers configurable inside the memory > controller. I do not think we need an elaborate interface. We just want to have a global boot time knob to overwrite the default behavior. This is few lines of code and it should give the sufficient flexibility. -- Michal Hocko SUSE Labs -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Miller <davem@davemloft.net> |
|---|---|
| Date | 2015-10-27 14:40 +0100 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qocDM-5L7-7@gated-at.bofh.it> |
| In reply to | #1256725 |
From: Michal Hocko <mhocko@kernel.org> Date: Tue, 27 Oct 2015 13:26:47 +0100 > On Mon 26-10-15 12:56:19, Johannes Weiner wrote: > [...] >> Or any other combination of pick-and-choose consumers. But >> honestly, nowadays all our paths are lockless, and the counting is an >> atomic-add-return with a per-cpu batch cache. > > You are still hooking into hot paths and there are users who want to > squeeze every single cycle from the HW. Yeah, you're basically probably undoing a half year of work by another developer who was able to remove an atomic from these paths. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Johannes Weiner <hannes@cmpxchg.org> |
|---|---|
| Date | 2015-10-27 16:50 +0100 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qoeFC-6WP-35@gated-at.bofh.it> |
| In reply to | #1256725 |
On Tue, Oct 27, 2015 at 01:26:47PM +0100, Michal Hocko wrote: > On Mon 26-10-15 12:56:19, Johannes Weiner wrote: > [...] > > Now you could argue that there might exist specialized workloads that > > need to account anonymous pages and page cache, but not socket memory > > buffers. > > Exactly, and there are loads doing this. Memcg groups are also created to > limit anon/page cache consumers to not affect the others running on > the system (basically in the root memcg context from memcg POV) which > don't care about tracking and they definitely do not want to pay for an > additional overhead. We should definitely be able to offer a global > disable knob for them. The same applies to kmem accounting in general. I don't see how you make such a clear distinction between, say, page cache and the dentry cache, and call one user memory and the other kernel memory. That just doesn't make sense to me. They're both kernel memory allocated on behalf of the user, the only difference being that one is tracked on the page level and the other on the slab level, and we started accounting one before the other. IMO that's an implementation detail and a historical artifact that should not be exposed to the user. And that's the thing I hate about the current opt-out knob. > > I don't think there is a compelling case for an elaborate interface > > to make individual memory consumers configurable inside the memory > > controller. > > I do not think we need an elaborate interface. We just want to have > a global boot time knob to overwrite the default behavior. This is > few lines of code and it should give the sufficient flexibility. Okay, then let's add this for the socket memory to start with. I'll have to think more about how to distinguish the slab-based consumers. Or maybe you have an idea. For now, something like this as a boot commandline? cgroup.memory=nosocket So again in summary, no default overhead until you create a cgroup to specifically track and account memory. And then, when you know what you are doing and have a specialized workload, you can disable socket memory as a specific consumer to remove that particular overhead while still being able to contain page cache, anon, kmem, whatever. Does that sound like reasonable userinterfacing to everyone? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2015-10-27 17:20 +0100 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qof8C-7mI-33@gated-at.bofh.it> |
| In reply to | #1256868 |
On Tue 27-10-15 11:41:38, Johannes Weiner wrote: > On Tue, Oct 27, 2015 at 01:26:47PM +0100, Michal Hocko wrote: > > On Mon 26-10-15 12:56:19, Johannes Weiner wrote: > > [...] > > > Now you could argue that there might exist specialized workloads that > > > need to account anonymous pages and page cache, but not socket memory > > > buffers. > > > > Exactly, and there are loads doing this. Memcg groups are also created to > > limit anon/page cache consumers to not affect the others running on > > the system (basically in the root memcg context from memcg POV) which > > don't care about tracking and they definitely do not want to pay for an > > additional overhead. We should definitely be able to offer a global > > disable knob for them. The same applies to kmem accounting in general. > > I don't see how you make such a clear distinction between, say, page > cache and the dentry cache, and call one user memory and the other > kernel memory. Because the kernel memory footprint would be so small that it simply doesn't change the picture at all. While the page cache or anonymous memory consumption might be so large it might be disruptive. I am talking about loads where good enough is better than "perfect" and ephemeral global memory pressure when kmem goes over expectations is better than a permanent cpu overhead. Whatever we do it will always be non-zero. Also kmem accounting will make the load more non-deterministic because many of the resources are shared between tasks in separate cgroups unless they are explicitly configured. E.g. [id]cache will be shared and first to touch gets charged so you would end up with more false sharing. Nevertheless, I do not want to shift the discussion from the topic. I just think that one-fits-all simply won't work. > That just doesn't make sense to me. They're both kernel > memory allocated on behalf of the user, the only difference being that > one is tracked on the page level and the other on the slab level, and > we started accounting one before the other. > > IMO that's an implementation detail and a historical artifact that > should not be exposed to the user. And that's the thing I hate about > the current opt-out knob. > > > > I don't think there is a compelling case for an elaborate interface > > > to make individual memory consumers configurable inside the memory > > > controller. > > > > I do not think we need an elaborate interface. We just want to have > > a global boot time knob to overwrite the default behavior. This is > > few lines of code and it should give the sufficient flexibility. > > Okay, then let's add this for the socket memory to start with. I'll > have to think more about how to distinguish the slab-based consumers. > Or maybe you have an idea. Isn't that as simple as enabling the jump label during the initialization depending on the knob value? All the charging paths should be disabled by default already. > For now, something like this as a boot commandline? > > cgroup.memory=nosocket That would work for me. I would even see a place to have CONFIG_MEMCG_TCP_KMEM_ENABLED config option for the default and [no]socket as a kernel parameter to override the configuratioin default. This would allow distributions to define their policy without enforcing it hard and those who compile the kernel to define their own policy. -- Michal Hocko SUSE Labs -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Johannes Weiner <hannes@cmpxchg.org> |
|---|---|
| Date | 2015-10-27 17:50 +0100 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qofBF-7xc-53@gated-at.bofh.it> |
| In reply to | #1256904 |
On Tue, Oct 27, 2015 at 05:15:54PM +0100, Michal Hocko wrote: > On Tue 27-10-15 11:41:38, Johannes Weiner wrote: > > On Tue, Oct 27, 2015 at 01:26:47PM +0100, Michal Hocko wrote: > > > On Mon 26-10-15 12:56:19, Johannes Weiner wrote: > > > [...] > > > > Now you could argue that there might exist specialized workloads that > > > > need to account anonymous pages and page cache, but not socket memory > > > > buffers. > > > > > > Exactly, and there are loads doing this. Memcg groups are also created to > > > limit anon/page cache consumers to not affect the others running on > > > the system (basically in the root memcg context from memcg POV) which > > > don't care about tracking and they definitely do not want to pay for an > > > additional overhead. We should definitely be able to offer a global > > > disable knob for them. The same applies to kmem accounting in general. > > > > I don't see how you make such a clear distinction between, say, page > > cache and the dentry cache, and call one user memory and the other > > kernel memory. > > Because the kernel memory footprint would be so small that it simply > doesn't change the picture at all. While the page cache or anonymous > memory consumption might be so large it might be disruptive. Or it could be exactly the other way around when you have a workload that is heavy on filesystem metadata. I don't see why any scenario would be more important than the other. I'm not saying that distinguishing between consumers is wrong, just that "user memory vs kernel memory" is a false classification. Why do you call page cache user memory but dentry cache kernel memory? It doesn't make any sense. > Also kmem accounting will make the load more non-deterministic because > many of the resources are shared between tasks in separate cgroups > unless they are explicitly configured. E.g. [id]cache will be shared > and first to touch gets charged so you would end up with more false > sharing. Exactly like page cache. This differentiation isn't based on reality. > Nevertheless, I do not want to shift the discussion from the topic. I > just think that one-fits-all simply won't work. Okay, this is something we can converge on. > > That just doesn't make sense to me. They're both kernel > > memory allocated on behalf of the user, the only difference being that > > one is tracked on the page level and the other on the slab level, and > > we started accounting one before the other. > > > > IMO that's an implementation detail and a historical artifact that > > should not be exposed to the user. And that's the thing I hate about > > the current opt-out knob. You carefully skipped over this part. We can ignore it for socket memory but it's something we need to figure out when it comes to slab accounting and tracking. > > > > I don't think there is a compelling case for an elaborate interface > > > > to make individual memory consumers configurable inside the memory > > > > controller. > > > > > > I do not think we need an elaborate interface. We just want to have > > > a global boot time knob to overwrite the default behavior. This is > > > few lines of code and it should give the sufficient flexibility. > > > > Okay, then let's add this for the socket memory to start with. I'll > > have to think more about how to distinguish the slab-based consumers. > > Or maybe you have an idea. > > Isn't that as simple as enabling the jump label during the > initialization depending on the knob value? All the charging paths > should be disabled by default already. You missed my point. It's not about the implementation, it's about how we present these choices to the user. Having page cache accounting built in while presenting dentry+inode cache as a configurable extension is completely random and doesn't make sense. They are both first class memory consumers. They're not separate categories. One isn't more "core" than the other. > > For now, something like this as a boot commandline? > > > > cgroup.memory=nosocket > > That would work for me. Okay, then I'll go that route for the socket stuff. Dave is that cool with you? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Miller <davem@davemloft.net> |
|---|---|
| Date | 2015-10-28 01:30 +0100 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qomMN-3GT-1@gated-at.bofh.it> |
| In reply to | #1256947 |
From: Johannes Weiner <hannes@cmpxchg.org> Date: Tue, 27 Oct 2015 09:42:27 -0700 > On Tue, Oct 27, 2015 at 05:15:54PM +0100, Michal Hocko wrote: >> > For now, something like this as a boot commandline? >> > >> > cgroup.memory=nosocket >> >> That would work for me. > > Okay, then I'll go that route for the socket stuff. > > Dave is that cool with you? Depends upon the default. Until the user configures something explicitly into the memory controller, the networking bits should all evaluate to nothing. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Johannes Weiner <hannes@cmpxchg.org> |
|---|---|
| Date | 2015-10-28 04:10 +0100 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qophD-5qX-9@gated-at.bofh.it> |
| In reply to | #1257502 |
On Tue, Oct 27, 2015 at 05:45:32PM -0700, David Miller wrote: > From: Johannes Weiner <hannes@cmpxchg.org> > Date: Tue, 27 Oct 2015 09:42:27 -0700 > > > On Tue, Oct 27, 2015 at 05:15:54PM +0100, Michal Hocko wrote: > >> > For now, something like this as a boot commandline? > >> > > >> > cgroup.memory=nosocket > >> > >> That would work for me. > > > > Okay, then I'll go that route for the socket stuff. > > > > Dave is that cool with you? > > Depends upon the default. > > Until the user configures something explicitly into the memory > controller, the networking bits should all evaluate to nothing. Yep, I'll stick them behind a default-off jump label again. This bootflag is only to override an active memory controller configuration and force-off that jump label permanently. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2015-10-29 16:30 +0100 |
| Subject | Re: [PATCH 5/8] mm: memcontrol: account socket memory on unified hierarchy |
| Message-ID | <qoXjm-1WA-55@gated-at.bofh.it> |
| In reply to | #1256947 |
On Tue 27-10-15 09:42:27, Johannes Weiner wrote: > On Tue, Oct 27, 2015 at 05:15:54PM +0100, Michal Hocko wrote: > > On Tue 27-10-15 11:41:38, Johannes Weiner wrote: [...] > Or it could be exactly the other way around when you have a workload > that is heavy on filesystem metadata. I don't see why any scenario > would be more important than the other. Yes I definitely agree. No scenario is more important. We can only come up with a default that makes more sense for the majority and allow the minority to override. That was what I wanted to say basically. > I'm not saying that distinguishing between consumers is wrong, just > that "user memory vs kernel memory" is a false classification. Why do > you call page cache user memory but dentry cache kernel memory? It > doesn't make any sense. We are not talking about dcache vs. page cache alone here, though. We are talking about _all_ slab allocations vs. only user accessed memory. The slab consumption is directly under kernel control. A great pile of this logic is completly hidden from userspace. While user can estimate the user memory it is hard (if possible) to do that for the kernel memory footprint - not even mentioning this is variable and dependent on the particular kernel version. > > Also kmem accounting will make the load more non-deterministic because > > many of the resources are shared between tasks in separate cgroups > > unless they are explicitly configured. E.g. [id]cache will be shared > > and first to touch gets charged so you would end up with more false > > sharing. > > Exactly like page cache. This differentiation isn't based on reality. Yes false sharing is an existing and long term problem already. I just wanted to point out that the false sharing would be even a bigger problem because some kernel tracked resources are shared more naturally than file sharing. > > > IMO that's an implementation detail and a historical artifact that > > > should not be exposed to the user. And that's the thing I hate about > > > the current opt-out knob. > > You carefully skipped over this part. We can ignore it for socket > memory but it's something we need to figure out when it comes to slab > accounting and tracking. I am sorry, I didn't mean to skip this part, I though it would be clear from the previous text. I think kmem accounting falls into the same category. Have a sane default and a global boottime knob to override it for those that think differently - for whatever reason they might have. [...] > Having page cache accounting built in while presenting dentry+inode > cache as a configurable extension is completely random and doesn't > make sense. They are both first class memory consumers. They're not > separate categories. One isn't more "core" than the other. Again we are talking about all slab allocations not just the dcache. > > > For now, something like this as a boot commandline? > > > > > > cgroup.memory=nosocket > > > > That would work for me. > > Okay, then I'll go that route for the socket stuff. Thanks! -- Michal Hocko SUSE Labs -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | linux.kernel
csiph-web