In order to fix no node to alloc memory, when we want to update mempolicy and
mems_allowed, we expand the set of nodes first (set all the newly nodes) and
shrink the set of nodes lazily(clean disallowed nodes), But the mempolicy's
rebind functions may breaks the expanding.
So we restructure the mempolicy's rebind functions and split the rebind work to
two steps, just like the update of cpuset's mems:
The 1st step: expand the set of the mempolicy's nodes.
The 2nd step: shrink the set of the mempolicy's nodes.
It is used when there is no real lock to protect the mempolicy in the read-side.
Otherwise we can do rebind work at once.
In order to implement it, we defined
enum mpol_rebind_step {
MPOL_REBIND_ONCE,
MPOL_REBIND_STEP1,
MPOL_REBIND_STEP2,
MPOL_REBIND_NSTEP,
};
If the mempolicy needn't be updated by two steps, we can pass MPOL_REBIND_ONCE
to the rebind functions. Or we can pass MPOL_REBIND_STEP1 to do the first step
of the rebind work and pass MPOL_REBIND_STEP2 to do the second step work.
Besides that, it maybe long time between these two step and we have to release
the lock that protects mempolicy and mems_allowed. If we hold the lock once
again, we must check whether the current mempolicy is under the rebinding (the
first step has been done) or not, because the task may alloc a new mempolicy
when we don't hold the lock. So we defined the following flag to identify it.
#define MPOL_F_REBINDING (1 << 2)
The new functions will be used in the next patch.
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
include/linux/mempolicy.h | 15 ++++-
kernel/cpuset.c | 4 +-
mm/mempolicy.c | 124 ++++++++++++++++++++++++++++++++++++++-------
3 files changed, 119 insertions(+), 24 deletions(-)
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 1cc966c..7b9ef6b 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -23,6 +23,13 @@ enum {
MPOL_MAX, /* always last member of enum */
};
...