[PATCH v2 23/28] lru: add an element to a memcg list

Kamezawa Hiroyuki kamezawa.hiroyu at jp.fujitsu.com
Mon Apr 1 08:18:32 UTC 2013


(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 at parallels.com>
> Cc: Dave Chinner <dchinner at redhat.com>
> Cc: Mel Gorman <mgorman at suse.de>
> Cc: Rik van Riel <riel at redhat.com>
> Cc: Johannes Weiner <hannes at cmpxchg.org>
> Cc: Michal Hocko <mhocko at suse.cz>
> Cc: Hugh Dickins <hughd at google.com>
> Cc: Kamezawa Hiroyuki <kamezawa.hiroyu at jp.fujitsu.com>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> ---
>   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



More information about the Containers mailing list