From: Glauber Costa <glommer@parallels.com>
To: linux-mm@kvack.org
Cc: cgroups@vger.kernel.org, Dave Shrinnker <david@fromorbit.com>,
Serge Hallyn <serge.hallyn@canonical.com>,
kamezawa.hiroyu@jp.fujitsu.com, Michal Hocko <mhocko@suse.cz>,
Johannes Weiner <hannes@cmpxchg.org>,
Andrew Morton <akpm@linux-foundation.org>,
hughd@google.com, linux-fsdevel@vger.kernel.org,
containers@lists.linux-foundation.org,
Greg Thelen <gthelen@google.com>,
Glauber Costa <glommer@parallels.com>,
Dave Chinner <dchinner@redhat.com>, Mel Gorman <mgorman@suse.de>,
Rik van Riel <riel@redhat.com>
Subject: [PATCH v3 25/32] list_lru: per-memcg walks
Date: Mon, 8 Apr 2013 18:00:52 +0400 [thread overview]
Message-ID: <1365429659-22108-26-git-send-email-glommer@parallels.com> (raw)
In-Reply-To: <1365429659-22108-1-git-send-email-glommer@parallels.com>
This patch extend the list_lru interfaces to allow for a memcg
parameter. Because most of its users won't need it, instead of
modifying the function signatures we create a new set of _memcg()
functions and write the old API ontop of that.
At this point, the infrastructure is mostly in place. We already walk
the nodes using all memcg indexes, so we just need to make sure we skip
all but the one we're interested in. We could just go directly to the
memcg of interest, but I am assuming that given the gained simplicity,
spending a few cycles here won't hurt *that* much (but that can be
improved if needed, of course).
Signed-off-by: Glauber Costa <glommer@parallels.com>
Cc: Dave Chinner <dchinner@redhat.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Rik van Riel <riel@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Hugh Dickins <hughd@google.com>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
include/linux/list_lru.h | 25 ++++++++++++++++-----
lib/list_lru.c | 56 ++++++++++++++++++++++++++++++++++++------------
2 files changed, 62 insertions(+), 19 deletions(-)
diff --git a/include/linux/list_lru.h b/include/linux/list_lru.h
index ea1ab4d..6f9e745 100644
--- a/include/linux/list_lru.h
+++ b/include/linux/list_lru.h
@@ -78,21 +78,36 @@ static inline int list_lru_init_memcg(struct list_lru *lru)
int list_lru_add(struct list_lru *lru, struct list_head *item);
int list_lru_del(struct list_lru *lru, struct list_head *item);
-long list_lru_count_nodemask(struct list_lru *lru, nodemask_t *nodes_to_count);
+
+long list_lru_count_nodemask_memcg(struct list_lru *lru,
+ nodemask_t *nodes_to_count, struct mem_cgroup *memcg);
+
+static inline long
+list_lru_count_nodemask(struct list_lru *lru, nodemask_t *nodes_to_count)
+{
+ return list_lru_count_nodemask_memcg(lru, nodes_to_count, NULL);
+}
static inline long list_lru_count(struct list_lru *lru)
{
return list_lru_count_nodemask(lru, &lru->active_nodes);
}
-
typedef enum lru_status
(*list_lru_walk_cb)(struct list_head *item, spinlock_t *lock, void *cb_arg);
-
typedef void (*list_lru_dispose_cb)(struct list_head *dispose_list);
-long list_lru_walk_nodemask(struct list_lru *lru, list_lru_walk_cb isolate,
- void *cb_arg, long nr_to_walk, nodemask_t *nodes_to_walk);
+long list_lru_walk_nodemask_memcg(struct list_lru *lru,
+ list_lru_walk_cb isolate, void *cb_arg, long nr_to_walk,
+ nodemask_t *nodes_to_walk, struct mem_cgroup *memcg);
+
+static inline long list_lru_walk_nodemask(struct list_lru *lru,
+ list_lru_walk_cb isolate, void *cb_arg, long nr_to_walk,
+ nodemask_t *nodes_to_walk)
+{
+ return list_lru_walk_nodemask_memcg(lru, isolate, cb_arg, nr_to_walk,
+ &lru->active_nodes, NULL);
+}
static inline long list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate,
void *cb_arg, long nr_to_walk)
diff --git a/lib/list_lru.c b/lib/list_lru.c
index dfc2c4a..3093f98 100644
--- a/lib/list_lru.c
+++ b/lib/list_lru.c
@@ -75,6 +75,11 @@ memcg_kmem_lru_of_page(struct list_lru *lru, struct page *page)
* memcg_limited_groups_array_size will be 0. _idx starts at -1, and it will
* still be allowed to execute once.
*
+ * If a memcg is specified at memcg_id, we will make sure that the loop only
+ * have one iteration, corresponding to that memcg. This makes sure that the
+ * interface is kept for both cases and there is no need for separate code to
+ * handle that case, at the price of complicating the macro a bit.
+ *
* We convention that for _idx = -1, the global node info should be used.
* After that, we will go through each of the memcgs, starting at 0.
*
@@ -83,8 +88,11 @@ memcg_kmem_lru_of_page(struct list_lru *lru, struct page *page)
* end. The old ones are just copied, and any interesting manipulation happen
* in the node list itself, and we already lock the list.
*/
-#define for_each_memcg_lru_index(_idx) \
- for ((_idx) = -1; ((_idx) < memcg_limited_groups_array_size); (_idx)++)
+#define for_each_memcg_lru_index(_idx, memcg_id) \
+ for ((_idx) = ((memcg_id) >= 0) ? memcg_id : -1; \
+ ((memcg_id < 0) || ((_idx) <= (memcg_id))) && \
+ ((_idx) < memcg_limited_groups_array_size); \
+ (_idx)++)
int
list_lru_add(
@@ -145,25 +153,44 @@ list_lru_del(
EXPORT_SYMBOL_GPL(list_lru_del);
long
-list_lru_count_nodemask(
+list_lru_count_nodemask_memcg(
struct list_lru *lru,
- nodemask_t *nodes_to_count)
+ nodemask_t *nodes_to_count,
+ struct mem_cgroup *memcg)
{
long count = 0;
int nid;
+ nodemask_t nodes;
+ struct list_lru_node *nlru;
+ int memcg_id = memcg_cache_id(memcg);
+
+ /*
+ * Conservative code can call this setting nodes with node_setall.
+ * This will generate an out of bound access for memcg.
+ */
+ nodes_and(nodes, *nodes_to_count, node_online_map);
- for_each_node_mask(nid, *nodes_to_count) {
+ for_each_node_mask(nid, nodes) {
/*
* We don't need to loop through all memcgs here, because we
* have the node_totals information for the node. If we hadn't,
* this would still be achieavable by a loop-over-all-groups
*/
- count += atomic_long_read(&lru->node_totals[nid]);
- }
+ if (!memcg)
+ count += atomic_long_read(&lru->node_totals[nid]);
+ else {
+ nlru = lru_node_of_index(lru, memcg_id, nid);
+ WARN_ON(!nlru);
+ spin_lock(&nlru->lock);
+ BUG_ON(nlru->nr_items < 0);
+ count += nlru->nr_items;
+ spin_unlock(&nlru->lock);
+ }
+ }
return count;
}
-EXPORT_SYMBOL_GPL(list_lru_count_nodemask);
+EXPORT_SYMBOL_GPL(list_lru_count_nodemask_memcg);
static long
list_lru_walk_node(
@@ -208,16 +235,18 @@ restart:
}
long
-list_lru_walk_nodemask(
+list_lru_walk_nodemask_memcg(
struct list_lru *lru,
list_lru_walk_cb isolate,
void *cb_arg,
long nr_to_walk,
- nodemask_t *nodes_to_walk)
+ nodemask_t *nodes_to_walk,
+ struct mem_cgroup *memcg)
{
long isolated = 0;
int nid;
nodemask_t nodes;
+ int memcg_id = memcg_cache_id(memcg);
int idx;
struct list_lru_node *nlru;
@@ -228,8 +257,7 @@ list_lru_walk_nodemask(
nodes_and(nodes, *nodes_to_walk, node_online_map);
for_each_node_mask(nid, nodes) {
- for_each_memcg_lru_index(idx) {
-
+ for_each_memcg_lru_index(idx, memcg_id) {
nlru = lru_node_of_index(lru, idx, nid);
if (!nlru)
continue;
@@ -242,7 +270,7 @@ list_lru_walk_nodemask(
}
return isolated;
}
-EXPORT_SYMBOL_GPL(list_lru_walk_nodemask);
+EXPORT_SYMBOL_GPL(list_lru_walk_nodemask_memcg);
static long
list_lru_dispose_all_node(
@@ -255,7 +283,7 @@ list_lru_dispose_all_node(
long disposed = 0;
int idx;
- for_each_memcg_lru_index(idx) {
+ for_each_memcg_lru_index(idx, -1) {
nlru = lru_node_of_index(lru, idx, nid);
if (!nlru)
continue;
--
1.8.1.4
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2013-04-08 14:02 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-08 14:00 [PATCH v3 00/32] memcg-aware slab shrinking with lasers and numbers Glauber Costa
2013-04-08 14:00 ` [PATCH v3 01/32] super: fix calculation of shrinkable objects for small numbers Glauber Costa
2013-04-08 14:00 ` [PATCH v3 02/32] vmscan: take at least one pass with shrinkers Glauber Costa
2013-04-08 14:00 ` [PATCH v3 03/32] dcache: convert dentry_stat.nr_unused to per-cpu counters Glauber Costa
2013-04-08 14:00 ` [PATCH v3 04/32] dentry: move to per-sb LRU locks Glauber Costa
2013-04-08 14:00 ` [PATCH v3 05/32] dcache: remove dentries from LRU before putting on dispose list Glauber Costa
2013-04-08 14:00 ` [PATCH v3 06/32] mm: new shrinker API Glauber Costa
2013-04-08 14:00 ` [PATCH v3 07/32] shrinker: convert superblock shrinkers to new API Glauber Costa
2013-04-08 14:00 ` [PATCH v3 08/32] list: add a new LRU list type Glauber Costa
2013-04-15 5:35 ` Greg Thelen
2013-04-15 17:56 ` Greg Thelen
2013-04-16 14:43 ` Glauber Costa
2013-04-08 14:00 ` [PATCH v3 09/32] inode: convert inode lru list to generic lru list code Glauber Costa
2013-04-08 14:00 ` [PATCH v3 10/32] dcache: convert to use new lru list infrastructure Glauber Costa
2013-04-08 14:00 ` [PATCH v3 11/32] list_lru: per-node " Glauber Costa
2013-04-15 5:37 ` Greg Thelen
2013-04-08 14:00 ` [PATCH v3 12/32] shrinker: add node awareness Glauber Costa
2013-04-15 5:38 ` Greg Thelen
2013-04-08 14:00 ` [PATCH v3 13/32] fs: convert inode and dentry shrinking to be node aware Glauber Costa
2013-04-08 14:00 ` [PATCH v3 14/32] xfs: convert buftarg LRU to generic code Glauber Costa
2013-04-15 5:38 ` Greg Thelen
2013-04-15 10:14 ` Glauber Costa
2013-04-08 14:00 ` [PATCH v3 15/32] xfs: convert dquot cache lru to list_lru Glauber Costa
2013-04-08 14:00 ` [PATCH v3 16/32] fs: convert fs shrinkers to new scan/count API Glauber Costa
2013-04-08 14:00 ` [PATCH v3 17/32] drivers: convert shrinkers to new count/scan API Glauber Costa
2013-04-08 14:00 ` [PATCH v3 18/32] shrinker: convert remaining shrinkers to " Glauber Costa
2013-04-08 14:00 ` [PATCH v3 19/32] hugepage: convert huge zero page shrinker to new shrinker API Glauber Costa
2013-04-15 5:38 ` Greg Thelen
2013-04-15 8:10 ` Kirill A. Shutemov
2013-04-08 14:00 ` [PATCH v3 20/32] shrinker: Kill old ->shrink API Glauber Costa
2013-04-15 5:38 ` Greg Thelen
2013-04-08 14:00 ` [PATCH v3 21/32] vmscan: also shrink slab in memcg pressure Glauber Costa
2013-04-08 14:00 ` [PATCH v3 22/32] memcg,list_lru: duplicate LRUs upon kmemcg creation Glauber Costa
2013-04-08 14:00 ` [PATCH v3 23/32] lru: add an element to a memcg list Glauber Costa
2013-04-08 14:00 ` [PATCH v3 24/32] list_lru: also include memcg lists in counts and scans Glauber Costa
2013-04-08 14:00 ` Glauber Costa [this message]
2013-04-08 14:00 ` [PATCH v3 26/32] memcg: per-memcg kmem shrinking Glauber Costa
2013-04-08 14:00 ` [PATCH v3 27/32] list_lru: reclaim proportionaly between memcgs and nodes Glauber Costa
2013-04-08 14:00 ` [PATCH v3 28/32] memcg: scan cache objects hierarchically Glauber Costa
2013-04-08 14:00 ` [PATCH v3 29/32] memcg: move initialization to memcg creation Glauber Costa
2013-04-08 14:00 ` [PATCH v3 30/32] memcg: shrink dead memcgs upon global memory pressure Glauber Costa
2013-04-08 14:00 ` [PATCH v3 31/32] super: targeted memcg reclaim Glauber Costa
2013-04-08 14:00 ` [PATCH v3 32/32] memcg: debugging facility to access dangling memcgs Glauber Costa
2013-04-08 20:51 ` [PATCH v3 00/32] memcg-aware slab shrinking with lasers and numbers Andrew Morton
2013-04-09 7:25 ` Glauber Costa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1365429659-22108-26-git-send-email-glommer@parallels.com \
--to=glommer@parallels.com \
--cc=akpm@linux-foundation.org \
--cc=cgroups@vger.kernel.org \
--cc=containers@lists.linux-foundation.org \
--cc=david@fromorbit.com \
--cc=dchinner@redhat.com \
--cc=gthelen@google.com \
--cc=hannes@cmpxchg.org \
--cc=hughd@google.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mgorman@suse.de \
--cc=mhocko@suse.cz \
--cc=riel@redhat.com \
--cc=serge.hallyn@canonical.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox