libata-sff: ap->[last_]ctl are SFF specific
[safe/jmp/linux-2.6] / include / linux / mempolicy.h
index 507bf5e..1cc966c 100644 (file)
@@ -44,6 +44,14 @@ enum {
 #define MPOL_MF_MOVE_ALL (1<<2)        /* Move every page to conform to mapping */
 #define MPOL_MF_INTERNAL (1<<3)        /* Internal flags start here */
 
+/*
+ * Internal flags that share the struct mempolicy flags word with
+ * "mode flags".  These flags are allocated from bit 0 up, as they
+ * are never OR'ed into the mode in mempolicy API arguments.
+ */
+#define MPOL_F_SHARED  (1 << 0)        /* identify shared policies */
+#define MPOL_F_LOCAL   (1 << 1)        /* preferred local allocation */
+
 #ifdef __KERNEL__
 
 #include <linux/mmzone.h>
@@ -51,6 +59,7 @@ enum {
 #include <linux/rbtree.h>
 #include <linux/spinlock.h>
 #include <linux/nodemask.h>
+#include <linux/pagemap.h>
 
 struct mm_struct;
 
@@ -73,14 +82,14 @@ struct mm_struct;
  * Mempolicy objects are reference counted.  A mempolicy will be freed when
  * mpol_put() decrements the reference count to zero.
  *
- * Copying policy objects:
- * mpol_copy() allocates a new mempolicy and copies the specified mempolicy
+ * Duplicating policy objects:
+ * mpol_dup() allocates a new mempolicy and copies the specified mempolicy
  * to the new storage.  The reference count of the new object is initialized
- * to 1, representing the caller of mpol_copy().
+ * to 1, representing the caller of mpol_dup().
  */
 struct mempolicy {
        atomic_t refcnt;
-       unsigned short policy;  /* See MPOL_* above */
+       unsigned short mode;    /* See MPOL_* above */
        unsigned short flags;   /* See set_mempolicy() MPOL_F_* above */
        union {
                short            preferred_node; /* preferred */
@@ -105,11 +114,36 @@ static inline void mpol_put(struct mempolicy *pol)
                __mpol_put(pol);
 }
 
-extern struct mempolicy *__mpol_copy(struct mempolicy *pol);
-static inline struct mempolicy *mpol_copy(struct mempolicy *pol)
+/*
+ * Does mempolicy pol need explicit unref after use?
+ * Currently only needed for shared policies.
+ */
+static inline int mpol_needs_cond_ref(struct mempolicy *pol)
+{
+       return (pol && (pol->flags & MPOL_F_SHARED));
+}
+
+static inline void mpol_cond_put(struct mempolicy *pol)
+{
+       if (mpol_needs_cond_ref(pol))
+               __mpol_put(pol);
+}
+
+extern struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol,
+                                         struct mempolicy *frompol);
+static inline struct mempolicy *mpol_cond_copy(struct mempolicy *tompol,
+                                               struct mempolicy *frompol)
+{
+       if (!frompol)
+               return frompol;
+       return __mpol_cond_copy(tompol, frompol);
+}
+
+extern struct mempolicy *__mpol_dup(struct mempolicy *pol);
+static inline struct mempolicy *mpol_dup(struct mempolicy *pol)
 {
        if (pol)
-               pol = __mpol_copy(pol);
+               pol = __mpol_dup(pol);
        return pol;
 }
 
@@ -149,8 +183,7 @@ struct shared_policy {
        spinlock_t lock;
 };
 
-void mpol_shared_policy_init(struct shared_policy *info, unsigned short policy,
-                               unsigned short flags, nodemask_t *nodes);
+void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol);
 int mpol_set_shared_policy(struct shared_policy *info,
                                struct vm_area_struct *vma,
                                struct mempolicy *new);
@@ -168,6 +201,7 @@ extern void mpol_fix_fork_child_flag(struct task_struct *p);
 extern struct zonelist *huge_zonelist(struct vm_area_struct *vma,
                                unsigned long addr, gfp_t gfp_flags,
                                struct mempolicy **mpol, nodemask_t **nodemask);
+extern bool init_nodemask_of_mempolicy(nodemask_t *mask);
 extern unsigned slab_node(struct mempolicy *policy);
 
 extern enum zone_type policy_zone;
@@ -181,6 +215,31 @@ static inline void check_highest_zone(enum zone_type k)
 int do_migrate_pages(struct mm_struct *mm,
        const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags);
 
+
+#ifdef CONFIG_TMPFS
+extern int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context);
+
+extern int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol,
+                       int no_context);
+#endif
+
+/* Check if a vma is migratable */
+static inline int vma_migratable(struct vm_area_struct *vma)
+{
+       if (vma->vm_flags & (VM_IO|VM_HUGETLB|VM_PFNMAP|VM_RESERVED))
+               return 0;
+       /*
+        * Migration allocates pages in the highest zone. If we cannot
+        * do so then migration (at least from node to node) is not
+        * possible.
+        */
+       if (vma->vm_file &&
+               gfp_zone(mapping_gfp_mask(vma->vm_file->f_mapping))
+                                                               < policy_zone)
+                       return 0;
+       return 1;
+}
+
 #else
 
 struct mempolicy {};
@@ -194,11 +253,21 @@ static inline void mpol_put(struct mempolicy *p)
 {
 }
 
+static inline void mpol_cond_put(struct mempolicy *pol)
+{
+}
+
+static inline struct mempolicy *mpol_cond_copy(struct mempolicy *to,
+                                               struct mempolicy *from)
+{
+       return from;
+}
+
 static inline void mpol_get(struct mempolicy *pol)
 {
 }
 
-static inline struct mempolicy *mpol_copy(struct mempolicy *old)
+static inline struct mempolicy *mpol_dup(struct mempolicy *old)
 {
        return NULL;
 }
@@ -212,8 +281,8 @@ static inline int mpol_set_shared_policy(struct shared_policy *info,
        return -EINVAL;
 }
 
-static inline void mpol_shared_policy_init(struct shared_policy *info,
-               unsigned short policy, unsigned short flags, nodemask_t *nodes)
+static inline void mpol_shared_policy_init(struct shared_policy *sp,
+                                               struct mempolicy *mpol)
 {
 }
 
@@ -260,6 +329,8 @@ static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma,
        return node_zonelist(0, gfp_flags);
 }
 
+static inline bool init_nodemask_of_mempolicy(nodemask_t *m) { return false; }
+
 static inline int do_migrate_pages(struct mm_struct *mm,
                        const nodemask_t *from_nodes,
                        const nodemask_t *to_nodes, int flags)
@@ -270,6 +341,21 @@ static inline int do_migrate_pages(struct mm_struct *mm,
 static inline void check_highest_zone(int k)
 {
 }
+
+#ifdef CONFIG_TMPFS
+static inline int mpol_parse_str(char *str, struct mempolicy **mpol,
+                               int no_context)
+{
+       return 1;       /* error */
+}
+
+static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol,
+                               int no_context)
+{
+       return 0;
+}
+#endif
+
 #endif /* CONFIG_NUMA */
 #endif /* __KERNEL__ */