(2013/03/29 18:14), Glauber Costa wrote: > With the infrastructure we now have, we can add an element to a memcg > LRU list instead of the global list. The memcg lists are still > per-node. > > Technically, we will never trigger per-node shrinking in the memcg is > short of memory. Therefore an alternative to this would be to add the > element to *both* a single-node memcg array and a per-node global array. > per-node shrinking by memcg pressure is not imporant, I think. > There are two main reasons for this design choice: > > 1) adding an extra list_head to each of the objects would waste 16-bytes > per object, always remembering that we are talking about 1 dentry + 1 > inode in the common case. This means a close to 10 % increase in the > dentry size, and a lower yet significant increase in the inode size. In > terms of total memory, this design pays 32-byte per-superblock-per-node > (size of struct list_lru_node), which means that in any scenario where > we have more than 10 dentries + inodes, we would already be paying more > memory in the two-list-heads approach than we will here with 1 node x 10 > superblocks. The turning point of course depends on the workload, but I > hope the figures above would convince you that the memory footprint is > in my side in any workload that matters. > > 2) The main drawback of this, namely, that we loose global LRU order, is > not really seen by me as a disadvantage: if we are using memcg to > isolate the workloads, global pressure should try to balance the amount > reclaimed from all memcgs the same way the shrinkers will already > naturally balance the amount reclaimed from each superblock. (This > patchset needs some love in this regard, btw). > > To help us easily tracking down which nodes have and which nodes doesn't > have elements in the list, we will count on an auxiliary node bitmap in > the global level. > > Signed-off-by: Glauber Costa <glommer@xxxxxxxxxxxxx> > Cc: Dave Chinner <dchinner@xxxxxxxxxx> > Cc: Mel Gorman <mgorman@xxxxxxx> > Cc: Rik van Riel <riel@xxxxxxxxxx> > Cc: Johannes Weiner <hannes@xxxxxxxxxxx> > Cc: Michal Hocko <mhocko@xxxxxxx> > Cc: Hugh Dickins <hughd@xxxxxxxxxx> > Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> > Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> > --- > include/linux/list_lru.h | 10 +++++++ > include/linux/memcontrol.h | 10 +++++++ > lib/list_lru.c | 68 +++++++++++++++++++++++++++++++++++++++------- > mm/memcontrol.c | 38 +++++++++++++++++++++++++- > 4 files changed, 115 insertions(+), 11 deletions(-) > > diff --git a/include/linux/list_lru.h b/include/linux/list_lru.h > index d6cf126..0856899 100644 > --- a/include/linux/list_lru.h > +++ b/include/linux/list_lru.h > @@ -26,6 +26,7 @@ struct list_lru_array { > > struct list_lru { > struct list_lru_node node[MAX_NUMNODES]; > + atomic_long_t node_totals[MAX_NUMNODES]; some comments will be helpful. > nodemask_t active_nodes; > #ifdef CONFIG_MEMCG_KMEM > struct list_head lrus; > @@ -40,10 +41,19 @@ int memcg_update_all_lrus(unsigned long num); > void list_lru_destroy(struct list_lru *lru); > void list_lru_destroy_memcg(struct mem_cgroup *memcg); > int __memcg_init_lru(struct list_lru *lru); > +struct list_lru_node * > +lru_node_of_index(struct list_lru *lru, int index, int nid); > #else > static inline void list_lru_destroy(struct list_lru *lru) > { > } > + > +static inline struct list_lru_node * > +lru_node_of_index(struct list_lru *lru, int index, int nid) > +{ > + BUG_ON(index < 0); /* index != -1 with !MEMCG_KMEM. Impossible */ > + return &lru->node[nid]; > +} > #endif I'm sorry ...what "lru_node_of_index" means ? What is the "index" ? Thanks, -Kame -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html