[patch 1/7] cpusets: add dirty map to struct address_space - Kernel

This is a discussion on [patch 1/7] cpusets: add dirty map to struct address_space - Kernel ; From: Christoph Lameter In a NUMA system it is helpful to know where the dirty pages of a mapping are located. That way we will be able to implement writeout for applications that are constrained to a portion of the ...

+ Reply to Thread
Results 1 to 12 of 12

Thread: [patch 1/7] cpusets: add dirty map to struct address_space

  1. [patch 1/7] cpusets: add dirty map to struct address_space

    From: Christoph Lameter

    In a NUMA system it is helpful to know where the dirty pages of a mapping
    are located. That way we will be able to implement writeout for
    applications that are constrained to a portion of the memory of the
    system as required by cpusets.

    This patch implements the management of dirty node maps for an address
    space through the following functions:

    cpuset_clear_dirty_nodes(mapping) Clear the map of dirty nodes

    cpuset_update_nodes(mapping, page) Record a node in the dirty nodes
    map

    cpuset_init_dirty_nodes(mapping) Initialization of the map


    The dirty map may be stored either directly in the mapping (for NUMA
    systems with less then BITS_PER_LONG nodes) or separately allocated for
    systems with a large number of nodes (f.e. ia64 with 1024 nodes).

    Updating the dirty map may involve allocating it first for large
    configurations. Therefore, we protect the allocation and setting of a
    node in the map through the tree_lock. The tree_lock is already taken
    when a page is dirtied so there is no additional locking overhead if we
    insert the updating of the nodemask there.

    The dirty map is only cleared (or freed) when the inode is cleared. At
    that point no pages are attached to the inode anymore and therefore it
    can be done without any locking. The dirty map therefore records all nodes
    that have been used for dirty pages by that inode until the inode is no
    longer used.

    Signed-off-by: Christoph Lameter
    Cc: Nick Piggin
    Cc: Peter Zijlstra
    Cc: Paul Menage
    Cc: Derek Fults
    Signed-off-by: David Rientjes
    ---
    fs/buffer.c | 2 +
    fs/fs-writeback.c | 7 ++++++
    fs/inode.c | 3 ++
    include/linux/cpuset.h | 51 +++++++++++++++++++++++++++++++++++++++++++
    include/linux/fs.h | 7 ++++++
    include/linux/writeback.h | 2 +
    kernel/cpuset.c | 53 +++++++++++++++++++++++++++++++++++++++++++++
    mm/page-writeback.c | 2 +
    8 files changed, 127 insertions(+), 0 deletions(-)

    diff --git a/fs/buffer.c b/fs/buffer.c
    --- a/fs/buffer.c
    +++ b/fs/buffer.c
    @@ -41,6 +41,7 @@
    #include
    #include
    #include
    +#include

    static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);

    @@ -719,6 +720,7 @@ static int __set_page_dirty(struct page *page,
    radix_tree_tag_set(&mapping->page_tree,
    page_index(page), PAGECACHE_TAG_DIRTY);
    }
    + cpuset_update_dirty_nodes(mapping, page);
    spin_unlock_irq(&mapping->tree_lock);
    __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);

    diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
    --- a/fs/fs-writeback.c
    +++ b/fs/fs-writeback.c
    @@ -23,6 +23,7 @@
    #include
    #include
    #include
    +#include
    #include "internal.h"


    @@ -487,6 +488,12 @@ void generic_sync_sb_inodes(struct super_block *sb,
    continue; /* blockdev has wrong queue */
    }

    + if (!cpuset_intersects_dirty_nodes(mapping, wbc->nodes)) {
    + /* No node pages under writeback */
    + requeue_io(inode);
    + continue;
    + }
    +
    /* Was this inode dirtied after sync_sb_inodes was called? */
    if (time_after(inode->dirtied_when, start))
    break;
    diff --git a/fs/inode.c b/fs/inode.c
    --- a/fs/inode.c
    +++ b/fs/inode.c
    @@ -22,6 +22,7 @@
    #include
    #include
    #include
    +#include

    /*
    * This is needed for the following functions:
    @@ -167,6 +168,7 @@ static struct inode *alloc_inode(struct super_block *sb)
    mapping->assoc_mapping = NULL;
    mapping->backing_dev_info = &default_backing_dev_info;
    mapping->writeback_index = 0;
    + cpuset_init_dirty_nodes(mapping);

    /*
    * If the block_device provides a backing_dev_info for client
    @@ -271,6 +273,7 @@ void clear_inode(struct inode *inode)
    bd_forget(inode);
    if (S_ISCHR(inode->i_mode) && inode->i_cdev)
    cd_forget(inode);
    + cpuset_clear_dirty_nodes(inode->i_mapping);
    inode->i_state = I_CLEAR;
    }

    diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
    --- a/include/linux/cpuset.h
    +++ b/include/linux/cpuset.h
    @@ -80,6 +80,36 @@ extern int current_cpuset_is_being_rebound(void);

    extern void rebuild_sched_domains(void);

    +/*
    + * We need macros since struct address_space is not defined yet
    + */
    +#if MAX_NUMNODES <= BITS_PER_LONG
    +#define cpuset_init_dirty_nodes(__mapping) \
    + (__mapping)->dirty_nodes = NODE_MASK_NONE
    +
    +#define cpuset_update_dirty_nodes(__mapping, __page) \
    + node_set(page_to_nid(__page), (__mapping)->dirty_nodes);
    +
    +#define cpuset_clear_dirty_nodes(__mapping) \
    + (__mapping)->dirty_nodes = NODE_MASK_NONE
    +
    +#define cpuset_intersects_dirty_nodes(__mapping, __nodemask_ptr) \
    + (!(__nodemask_ptr) || \
    + nodes_intersects((__mapping)->dirty_nodes, *(__nodemask_ptr)))
    +
    +#else
    +struct address_space;
    +
    +#define cpuset_init_dirty_nodes(__mapping) \
    + (__mapping)->dirty_nodes = NULL
    +
    +extern void cpuset_update_dirty_nodes(struct address_space *mapping,
    + struct page *page);
    +extern void cpuset_clear_dirty_nodes(struct address_space *mapping);
    +extern int cpuset_intersects_dirty_nodes(struct address_space *mapping,
    + nodemask_t *mask);
    +#endif
    +
    #else /* !CONFIG_CPUSETS */

    static inline int cpuset_init_early(void) { return 0; }
    @@ -163,6 +193,27 @@ static inline void rebuild_sched_domains(void)
    partition_sched_domains(1, NULL, NULL);
    }

    +struct address_space;
    +
    +static inline void cpuset_init_dirty_nodes(struct address_space *mapping)
    +{
    +}
    +
    +static inline void cpuset_update_dirty_nodes(struct address_space *mapping,
    + struct page *page)
    +{
    +}
    +
    +static inline void cpuset_clear_dirty_nodes(struct address_space *mapping)
    +{
    +}
    +
    +static inline int cpuset_intersects_dirty_nodes(struct address_space *mapping,
    + nodemask_t *mask)
    +{
    + return 1;
    +}
    +
    #endif /* !CONFIG_CPUSETS */

    #endif /* _LINUX_CPUSET_H */
    diff --git a/include/linux/fs.h b/include/linux/fs.h
    --- a/include/linux/fs.h
    +++ b/include/linux/fs.h
    @@ -544,6 +544,13 @@ struct address_space {
    spinlock_t private_lock; /* for use by the address_space */
    struct list_head private_list; /* ditto */
    struct address_space *assoc_mapping; /* ditto */
    +#ifdef CONFIG_CPUSETS
    +#if MAX_NUMNODES <= BITS_PER_LONG
    + nodemask_t dirty_nodes; /* nodes with dirty pages */
    +#else
    + nodemask_t *dirty_nodes; /* pointer to mask, if dirty */
    +#endif
    +#endif
    } __attribute__((aligned(sizeof(long))));
    /*
    * On most architectures that alignment is already the case; but
    diff --git a/include/linux/writeback.h b/include/linux/writeback.h
    --- a/include/linux/writeback.h
    +++ b/include/linux/writeback.h
    @@ -72,6 +72,8 @@ struct writeback_control {
    * so we use a single control to update them
    */
    unsigned no_nrwrite_index_update:1;
    +
    + nodemask_t *nodes; /* Nodemask to writeback */
    };

    /*
    diff --git a/kernel/cpuset.c b/kernel/cpuset.c
    --- a/kernel/cpuset.c
    +++ b/kernel/cpuset.c
    @@ -16,6 +16,7 @@
    * 2006 Rework by Paul Menage to use generic cgroups
    * 2008 Rework of the scheduler domains and CPU hotplug handling
    * by Max Krasnyansky
    + * 2008 Cpuset writeback by Christoph Lameter
    *
    * This file is subject to the terms and conditions of the GNU General Public
    * License. See the file COPYING in the main directory of the Linux
    @@ -2323,6 +2324,58 @@ int cpuset_mem_spread_node(void)
    }
    EXPORT_SYMBOL_GPL(cpuset_mem_spread_node);

    +#if MAX_NUMNODES > BITS_PER_LONG
    +/*
    + * Special functions for NUMA systems with a large number of nodes. The
    + * nodemask is pointed to from the address_space structure. The attachment of
    + * the dirty_nodes nodemask is protected by the tree_lock. The nodemask is
    + * freed only when the inode is cleared (and therefore unused, thus no locking
    + * is necessary).
    + */
    +void cpuset_update_dirty_nodes(struct address_space *mapping,
    + struct page *page)
    +{
    + nodemask_t *nodes = mapping->dirty_nodes;
    + int node = page_to_nid(page);
    +
    + if (!nodes) {
    + nodes = kmalloc(sizeof(nodemask_t), GFP_ATOMIC);
    + if (!nodes)
    + return;
    +
    + *nodes = NODE_MASK_NONE;
    + mapping->dirty_nodes = nodes;
    + }
    + node_set(node, *nodes);
    +}
    +
    +void cpuset_clear_dirty_nodes(struct address_space *mapping)
    +{
    + nodemask_t *nodes = mapping->dirty_nodes;
    +
    + if (nodes) {
    + mapping->dirty_nodes = NULL;
    + kfree(nodes);
    + }
    +}
    +
    +/*
    + * Called without tree_lock. The nodemask is only freed when the inode is
    + * cleared and therefore this is safe.
    + */
    +int cpuset_intersects_dirty_nodes(struct address_space *mapping,
    + nodemask_t *mask)
    +{
    + nodemask_t *dirty_nodes = mapping->dirty_nodes;
    +
    + if (!mask)
    + return 1;
    + if (!dirty_nodes)
    + return 0;
    + return nodes_intersects(*dirty_nodes, *mask);
    +}
    +#endif
    +
    /**
    * cpuset_mems_allowed_intersects - Does @tsk1's mems_allowed intersect @tsk2's?
    * @tsk1: pointer to task_struct of some task.
    diff --git a/mm/page-writeback.c b/mm/page-writeback.c
    --- a/mm/page-writeback.c
    +++ b/mm/page-writeback.c
    @@ -34,6 +34,7 @@
    #include
    #include
    #include
    +#include

    /*
    * The maximum number of pages to writeout in a single bdflush/kupdate
    @@ -1104,6 +1105,7 @@ int __set_page_dirty_nobuffers(struct page *page)
    radix_tree_tag_set(&mapping->page_tree,
    page_index(page), PAGECACHE_TAG_DIRTY);
    }
    + cpuset_update_dirty_nodes(mapping, page);
    spin_unlock_irq(&mapping->tree_lock);
    if (mapping->host) {
    /* !PageAnon && !swapper_space */
    --
    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/

  2. Re: [patch 1/7] cpusets: add dirty map to struct address_space

    On Tue, 2008-10-28 at 09:08 -0700, David Rientjes wrote:

    > This patch implements the management of dirty node maps for an address
    > space through the following functions:
    >
    > cpuset_clear_dirty_nodes(mapping) Clear the map of dirty nodes
    >
    > cpuset_update_nodes(mapping, page) Record a node in the dirty nodes
    > map
    >
    > cpuset_init_dirty_nodes(mapping) Initialization of the map
    >
    >
    > The dirty map may be stored either directly in the mapping (for NUMA
    > systems with less then BITS_PER_LONG nodes) or separately allocated for
    > systems with a large number of nodes (f.e. ia64 with 1024 nodes).
    >
    > Updating the dirty map may involve allocating it first for large
    > configurations. Therefore, we protect the allocation and setting of a
    > node in the map through the tree_lock. The tree_lock is already taken
    > when a page is dirtied so there is no additional locking overhead if we
    > insert the updating of the nodemask there.


    I find this usage of tree lock most bothersome, as my concurrent
    pagecache patches take the lock out. In which case this _does_ cause
    extra locking overhead.

    --
    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/

  3. Re: [patch 3/7] mm: make page writeback obey cpuset constraints

    On Tue, 2008-10-28 at 09:08 -0700, David Rientjes wrote:

    > + is_subset = cpuset_populate_dirty_limits(dl, &dirtyable_memory,
    > + &nr_mapped, nodes);
    > + if (!is_subset) {
    > + dl->nr_dirty = global_page_state(NR_FILE_DIRTY);
    > + dl->nr_unstable = global_page_state(NR_UNSTABLE_NFS);
    > + dl->nr_writeback = global_page_state(NR_WRITEBACK);
    > + dirtyable_memory = determine_dirtyable_memory();
    > + nr_mapped = global_page_state(NR_FILE_MAPPED) +
    > + global_page_state(NR_ANON_PAGES);
    > + } else
    > + dirtyable_memory -= highmem_dirtyable_memory(nodes,
    > + dirtyable_memory);


    Why not fold that all into cpuset_populate_dirty_limits() ?

    --
    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/

  4. Re: [patch 3/7] mm: make page writeback obey cpuset constraints

    On Tue, 2008-10-28 at 09:08 -0700, David Rientjes wrote:

    > +/*
    > + * Calculate the limits relative to the current cpuset
    > + *
    > + * We do not disregard highmem because all nodes (except maybe node 0) have
    > + * either all memory in HIGHMEM (32-bit) or all memory in non-HIGHMEM (64-bit).
    > + * If we would disregard highmem, then cpuset throttling would not work on
    > + * 32-bit.
    > + */
    > +int cpuset_populate_dirty_limits(struct dirty_limits *dl,
    > + unsigned long *dirtyable_memory,
    > + unsigned long *nr_mapped,
    > + const nodemask_t *nodes)
    > +{
    > + int node;
    > +
    > + if (likely(!nodes || nodes_subset(node_online_map, *nodes)))
    > + return 0;
    > + for_each_node_mask(node, *nodes) {
    > + if (!node_online(node))
    > + continue;
    > + dl->nr_dirty += node_page_state(node, NR_FILE_DIRTY);
    > + dl->nr_unstable += node_page_state(node, NR_UNSTABLE_NFS);
    > + dl->nr_writeback += node_page_state(node, NR_WRITEBACK);
    > + dirtyable_memory +=


    *dirtyable_memory perhaps?

    > + node_page_state(node, NR_ACTIVE_ANON) +
    > + node_page_state(node, NR_ACTIVE_FILE) +
    > + node_page_state(node, NR_INACTIVE_ANON) +
    > + node_page_state(node, NR_INACTIVE_FILE) +
    > + node_page_state(node, NR_FREE_PAGES);
    > + nr_mapped +=


    idem?

    > + node_page_state(node, NR_FILE_MAPPED) +
    > + node_page_state(node, NR_ANON_PAGES);
    > + }
    > + return 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/

  5. Re: [patch 1/7] cpusets: add dirty map to struct address_space

    On Tue, 2008-10-28 at 09:08 -0700, David Rientjes wrote:
    > @@ -487,6 +488,12 @@ void generic_sync_sb_inodes(struct super_block *sb,
    > continue; /* blockdev has wrong queue */
    > }
    >
    > + if (!cpuset_intersects_dirty_nodes(mapping, wbc->nodes)) {
    > + /* No node pages under writeback */
    > + requeue_io(inode);
    > + continue;
    > + }


    So, aside from all the dirty limit and passing node masks around, this
    is the magic bit?

    I totally missed it first time around, a short mention in the changelog
    might not be undeserved.

    --
    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/

  6. Re: [patch 6/7] cpusets: per cpuset dirty ratios

    On Tue, Oct 28, 2008 at 9:08 AM, David Rientjes wrote:
    > From: Christoph Lameter
    >
    > This implements dirty ratios per cpuset. Two new files are added to the
    > cpuset directories:


    Wouldn't this be equally applicable to cgroups using the memory
    controller rather than cpusets? Might it make sense to have a common
    subsystem that could be used by either of them?

    Paul
    --
    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/

  7. Re: [patch 1/7] cpusets: add dirty map to struct address_space

    On Tue, 2008-10-28 at 18:13 -0700, David Rientjes wrote:
    > On Tue, 28 Oct 2008, David Rientjes wrote:
    >
    > > Yeah, if we don't serialize with tree_lock then we'll need to protect the
    > > attachment of mapping->dirty_nodes with a new spinlock in struct
    > > address_space (and only for configs where MAX_NUMNODES > BITS_PER_LONG).
    > > That locking overhead is negligible when mapping->dirty_nodes is non-NULL
    > > since there's no requirement to protect the setting of the node in the
    > > nodemask.
    > >
    > > Are your concurrent pagecache patches in the latest mmotm? If so, I can
    > > rebase this entire patchset off that.

    >
    > We're still taking mapping->tree_lock in both __set_page_dirty() and
    > __set_page_dirty_nobuffers() in today's mmotm.
    >
    > When tree_lock is removed with your patchset, we can add a spinlock to
    > protect mapping->dirty_nodes when MAX_NUMNODES > BITS_PER_LONG.
    >
    > Would you like to fold this patch into your series (which assumes we're
    > not taking mapping->tree_lock in either of the two callers above)?


    Thanks!, I was working on cleaning up the patches to submit again
    soonish.


    --
    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/

  8. Re: [patch 6/7] cpusets: per cpuset dirty ratios

    On Tue, 2008-10-28 at 09:08 -0700, David Rientjes wrote:

    > +/*
    > + * Determine the dirty ratios for the currently active cpuset
    > + */
    > +void cpuset_get_current_dirty_ratios(int *background, int *throttle)
    > +{
    > + mutex_lock(&callback_mutex);
    > + task_lock(current);
    > + *background = task_cs(current)->dirty_background_ratio;
    > + *throttle = task_cs(current)->cpuset_dirty_ratio;
    > + task_unlock(current);
    > + mutex_unlock(&callback_mutex);
    > +
    > + if (*background == -1)
    > + *background = dirty_background_ratio;
    > + if (*throttle == -1)
    > + *throttle = vm_dirty_ratio;
    > +}


    That's rather an awful lot of locking to read just two integers.


    --
    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/

  9. Re: [patch 3/7] mm: make page writeback obey cpuset constraints

    On Tue, 2008-10-28 at 12:18 -0700, David Rientjes wrote:
    > On Tue, 28 Oct 2008, Peter Zijlstra wrote:
    >
    > > > + is_subset = cpuset_populate_dirty_limits(dl, &dirtyable_memory,
    > > > + &nr_mapped, nodes);
    > > > + if (!is_subset) {
    > > > + dl->nr_dirty = global_page_state(NR_FILE_DIRTY);
    > > > + dl->nr_unstable = global_page_state(NR_UNSTABLE_NFS);
    > > > + dl->nr_writeback = global_page_state(NR_WRITEBACK);
    > > > + dirtyable_memory = determine_dirtyable_memory();
    > > > + nr_mapped = global_page_state(NR_FILE_MAPPED) +
    > > > + global_page_state(NR_ANON_PAGES);
    > > > + } else
    > > > + dirtyable_memory -= highmem_dirtyable_memory(nodes,
    > > > + dirtyable_memory);

    > >
    > > Why not fold that all into cpuset_populate_dirty_limits() ?
    > >

    >
    > cpuset_populate_dirty_limits() is a no-op on !CONFIG_CPUSETS kernels.


    Right, humm. Maybe introduce a populate_dirty_limits() and differentiate
    that between CONFIG_CPUSETS and not, and make it do everything.

    That would get rid of this fudge I think, no?
    --
    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/

  10. Re: [patch 3/7] mm: make page writeback obey cpuset constraints

    On Thu, 2008-10-30 at 02:10 -0700, David Rientjes wrote:

    > So perhaps the solution is to introduce populate_nodemask_dirty_limits()
    > and populate_global_dirty_limits() both in mm/page-writeback.c?


    Sure, sounds good.
    --
    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/

  11. Re: [patch 6/7] cpusets: per cpuset dirty ratios

    On Thu, 2008-10-30 at 02:03 -0700, David Rientjes wrote:
    > On Thu, 30 Oct 2008, Peter Zijlstra wrote:
    >
    > > On Tue, 2008-10-28 at 09:08 -0700, David Rientjes wrote:
    > >
    > > > +/*
    > > > + * Determine the dirty ratios for the currently active cpuset
    > > > + */
    > > > +void cpuset_get_current_dirty_ratios(int *background, int *throttle)
    > > > +{
    > > > + mutex_lock(&callback_mutex);
    > > > + task_lock(current);
    > > > + *background = task_cs(current)->dirty_background_ratio;
    > > > + *throttle = task_cs(current)->cpuset_dirty_ratio;
    > > > + task_unlock(current);
    > > > + mutex_unlock(&callback_mutex);
    > > > +
    > > > + if (*background == -1)
    > > > + *background = dirty_background_ratio;
    > > > + if (*throttle == -1)
    > > > + *throttle = vm_dirty_ratio;
    > > > +}

    > >
    > > That's rather an awful lot of locking to read just two integers.
    > >

    >
    > As far as I know, task_lock(current) is required to dereference
    > task_cs(current) and callback_mutex is required to ensure its the same
    > cpuset.


    Since we read these things for every evaluation, getting it wrong isn't
    too harmful.

    So I would suggest just enough locking to ensure we don't reference any
    NULL pointers and such.

    IIRC the cpuset stuff is RCU freed, so some racy read should be
    possible, no?
    --
    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/

  12. Re: [patch 6/7] cpusets: per cpuset dirty ratios

    On Wed, 29 Oct 2008, Paul Menage wrote:

    > Wouldn't this be equally applicable to cgroups using the memory
    > controller rather than cpusets? Might it make sense to have a common
    > subsystem that could be used by either of them?


    Yes that would be useful.

    --
    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/

+ Reply to Thread