Linux Kernel
3.7.1
|
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/cpuset.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/list.h>
#include <linux/mempolicy.h>
#include <linux/mm.h>
#include <linux/memory.h>
#include <linux/export.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/pagemap.h>
#include <linux/proc_fs.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/security.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/time.h>
#include <linux/backing-dev.h>
#include <linux/sort.h>
#include <asm/uaccess.h>
#include <linux/atomic.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/cgroup.h>
Go to the source code of this file.
Data Structures | |
struct | fmeter |
struct | cpuset |
Macros | |
#define | CPUSET_NAME_LEN (128) |
#define | CPUSET_NODELIST_LEN (256) |
#define | FM_COEF 933 /* coefficient for half-life of 10 secs */ |
#define | FM_MAXTICKS ((time_t)99) /* useless computing more ticks than this */ |
#define | FM_MAXCNT 1000000 /* limit cnt to avoid overflow */ |
#define | FM_SCALE 1000 /* faux fixed point scale */ |
Variables | |
int number_of_cpusets | __read_mostly |
struct cgroup_subsys | cpuset_subsys |
#define FM_COEF 933 /* coefficient for half-life of 10 secs */ |
enum cpuset_filetype_t |
enum cpuset_flagbits_t |
enum hotplug_event |
cpuset_memory_pressure_bump - keep stats of per-cpuset reclaims.
Keep a running average of the rate of synchronous (direct) page reclaim efforts initiated by tasks in each cpuset.
This represents the rate at which some task in the cpuset ran low on memory on all nodes it was allowed to use, and had to enter the kernels page reclaim code in an effort to create more free memory by tossing clean pages or swapping or writing dirty pages.
Display to user space in the per-cpuset read-only file "memory_pressure". Value displayed is an integer representing the recent rate of entry into the synchronous (direct) page reclaim by any task attached to the cpuset.
cpuset_node_allowed_softwall - Can we allocate on a memory node? : is this an allowed node? : memory allocation flags
If we're in interrupt, yes, we can always allocate. If __GFP_THISNODE is set, yes, we can always allocate. If node is in our task's mems_allowed, yes. If it's not a __GFP_HARDWALL request and this node is in the nearest hardwalled cpuset ancestor to this task's cpuset, yes. If the task has been OOM killed and has access to memory reserves as specified by the TIF_MEMDIE flag, yes. Otherwise, no.
If __GFP_HARDWALL is set, cpuset_node_allowed_softwall() reduces to cpuset_node_allowed_hardwall(). Otherwise, cpuset_node_allowed_softwall() might sleep, and might allow a node from an enclosing cpuset.
cpuset_node_allowed_hardwall() only handles the simpler case of hardwall cpusets, and never sleeps.
The __GFP_THISNODE placement logic is really handled elsewhere, by forcibly using a zonelist starting at a specified node, and by (in get_page_from_freelist()) refusing to consider the zones for any node on the zonelist except the first. By the time any such calls get to this routine, we should just shut up and say 'yes'.
GFP_USER allocations are marked with the __GFP_HARDWALL bit, and do not allow allocations outside the current tasks cpuset unless the task has been OOM killed as is marked TIF_MEMDIE. GFP_KERNEL allocations are not so marked, so can escape to the nearest enclosing hardwalled ancestor cpuset.
Scanning up parent cpusets requires callback_mutex. The __alloc_pages() routine only calls here with __GFP_HARDWALL bit not set if it's a GFP_KERNEL allocation, and all nodes in the current tasks mems_allowed came up empty on the first pass over the zonelist. So only GFP_KERNEL allocations, if all nodes in the cpuset are short of memory, might require taking the callback_mutex mutex.
The first call here from mm/page_alloc:get_page_from_freelist() has __GFP_HARDWALL set in gfp_mask, enforcing hardwall cpusets, so no allocation on a node outside the cpuset is allowed (unless in interrupt, of course).
The second pass through get_page_from_freelist() doesn't even call here for GFP_ATOMIC calls. For those calls, the __alloc_pages() variable 'wait' is not set, and the bit ALLOC_CPUSET is not set in alloc_flags. That logic and the checks below have the combined affect that: in_interrupt - any node ok (current task context irrelevant) GFP_ATOMIC - any node ok TIF_MEMDIE - any node ok GFP_KERNEL - any node in enclosing hardwalled cpuset ok GFP_USER - only nodes in current tasks mems allowed ok.
Rule: Don't call cpuset_node_allowed_softwall if you can't sleep, unless you pass in the __GFP_HARDWALL flag set in gfp_flag, which disables the code that might scan up ancestor cpusets and sleep.
void cpuset_cpus_allowed | ( | struct task_struct * | tsk, |
struct cpumask * | pmask | ||
) |
cpuset_cpus_allowed - return cpus_allowed mask from a tasks cpuset. : pointer to task_struct from which to obtain cpuset->cpus_allowed. : pointer to struct cpumask variable to receive cpus_allowed set.
Description: Returns the cpumask_var_t cpus_allowed of the cpuset attached to the specified . Guaranteed to return some non-empty subset of cpu_online_mask, even if this means going outside the tasks cpuset.
void cpuset_cpus_allowed_fallback | ( | struct task_struct * | tsk | ) |
nodemask_t cpuset_mems_allowed | ( | struct task_struct * | tsk | ) |
cpuset_mems_allowed - return mems_allowed mask from a tasks cpuset. : pointer to task_struct from which to obtain cpuset->mems_allowed.
Description: Returns the nodemask_t mems_allowed of the cpuset attached to the specified . Guaranteed to return some non-empty subset of node_states[N_HIGH_MEMORY], even if this means going outside the tasks cpuset.
int cpuset_mems_allowed_intersects | ( | const struct task_struct * | tsk1, |
const struct task_struct * | tsk2 | ||
) |
cpuset_mems_allowed_intersects - Does 's mems_allowed intersect 's? : pointer to task_struct of some task. : pointer to task_struct of some other task.
Description: Return true if 's mems_allowed intersects the mems_allowed of . Used by the OOM killer to determine if one of the task's memory usage might impact the memory available to the other.
int cpuset_nodemask_valid_mems_allowed | ( | nodemask_t * | nodemask | ) |
void cpuset_print_task_mems_allowed | ( | struct task_struct * | tsk | ) |
cpuset_print_task_mems_allowed - prints task's cpuset and mems_allowed : pointer to task_struct of some task.
Description: Prints 's name, cpuset name, and cached copy of its mems_allowed to the kernel log. Must hold task_lock(task) to allow dereferencing task_cs(task).
void cpuset_task_status_allowed | ( | struct seq_file * | m, |
struct task_struct * | task | ||
) |
EXPORT_SYMBOL_GPL | ( | cpuset_mem_spread_node | ) |
struct cgroup_subsys cpuset_subsys |