Re: [PATCH] String conversions for memory policy

From: Christoph Lameter
Date: Tue Aug 02 2005 - 12:50:26 EST


On Mon, 1 Aug 2005, Paul Jackson wrote:

> There should probably be comments that these routines must
> execute in the context of the task whose mempolicies are
> being displayed or modified.

Ok. The str_to_mpol function needs to be executed from the task whose
memory policies are to be displayed but why would mpol_to_str need that?

I am quite concerned about policy layer due to :

1. No separation between sys_ and do_ functions. Its not easy to
use any of the policy functions from the kernel itself.
2. The bind strangeness. Does not preserve locality of allocation and
simply uses lower nodes first. This is quite
surprising and not mentioned in the documentation.
3. Mixing nodemask_t and bitmaps (probably due to user space variable
bitmap sizes). May not be clean due to not doing 1.
4. Unexpected side effects of some functions (like get_nodes updating the
current mems allowed, the filtering by nodes allowed).

All of this probably makes the policy layer difficult to maintain. Thus
only a restricted set of people that are competent on it.

New patch:

---

String conversions for memory policy

This patch adds two new functions to mm/mempolicy.c that allow the conversion
of a memory policy to a textual representation and vice versa.

Syntax of textual representation:

default
preferred=<nodenumber>
bind=<nodelist>
interleave=<nodelist>

Signed-off-by: Christoph Lameter <christoph@xxxxxxxxxxx>

Index: linux-2.6.13-rc4-mm1/mm/mempolicy.c
===================================================================
--- linux-2.6.13-rc4-mm1.orig/mm/mempolicy.c 2005-08-01 12:59:49.000000000 -0700
+++ linux-2.6.13-rc4-mm1/mm/mempolicy.c 2005-08-02 10:38:50.000000000 -0700
@@ -1170,3 +1170,101 @@
{
sys_set_mempolicy(MPOL_DEFAULT, NULL, 0);
}
+
+static const char *policy_types[] = { "default", "prefer", "bind", "interleave" };
+
+/*
+ * Convert a mempolicy into a string.
+ * Returns the number of characters in buffer (if positive)
+ * or an error (negative)
+ *
+ * May be called from outside of the context of a task.
+ */
+int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol)
+{
+ char *p = buffer;
+ int l;
+ nodemask_t nodes;
+ int mode = pol ? pol->policy : MPOL_DEFAULT;
+
+ switch (mode) {
+ case MPOL_DEFAULT:
+ nodes_clear(nodes);
+ break;
+
+ case MPOL_PREFERRED:
+ nodes_clear(nodes);
+ node_set(pol->v.preferred_node, nodes);
+ break;
+
+ case MPOL_BIND:
+ get_zonemask(pol, nodes.bits);
+ break;
+
+ case MPOL_INTERLEAVE:
+ nodes = * (nodemask_t *)pol->v.nodes;
+ break;
+
+ default:
+ BUG();
+ return -EFAULT;
+ }
+
+ l = strlen(policy_types[mode]);
+ if (buffer + maxlen < p + l + 1)
+ return -ENOSPC;
+
+ strcpy(p, policy_types[mode]);
+ p += l;
+
+ if (!nodes_empty(nodes)) {
+
+ if (buffer + maxlen < p + 2)
+ return -ENOSPC;
+
+ *p++ = '=';
+ p += nodelist_scnprintf(p, buffer + maxlen - p, nodes);
+ }
+ return p - buffer;
+}
+
+/*
+ * Convert a representation of a memory policy from text
+ * form to binary. This can only be done from the tasks that
+ * is using the memory policy since the nodes used by a policy
+ * may be restricted by the cpuset.
+ *
+ * Returns either a memory policy or NULL for error.
+ */
+struct mempolicy *str_to_mpol(char *buffer)
+{
+ nodemask_t nodes;
+ int mode;
+ int l;
+
+ for (mode = 0; mode <= MPOL_MAX; mode++) {
+ l = strlen(policy_types[mode]);
+ if (strnicmp(policy_types[mode], buffer, l)
+ && (mode == MPOL_DEFAULT || buffer[l] == '='))
+ break;
+ }
+
+ if (mode > MPOL_MAX)
+ return NULL;
+
+ if (mode == MPOL_DEFAULT)
+ return &default_policy;
+
+ if (nodelist_parse(buffer + l + 1, nodes) || nodes_empty(nodes))
+ return NULL;
+
+ /* Update current mems_allowed */
+ cpuset_update_current_mems_allowed();
+ /* Ignore nodes not set in current->mems_allowed */
+ cpuset_restrict_to_mems_allowed(nodes.bits);
+
+ if (!mpol_check_policy(mode, nodes.bits))
+ return NULL;
+
+ return mpol_new(mode, nodes.bits);
+}
Index: linux-2.6.13-rc4-mm1/include/linux/mempolicy.h
===================================================================
--- linux-2.6.13-rc4-mm1.orig/include/linux/mempolicy.h 2005-08-01 12:59:45.000000000 -0700
+++ linux-2.6.13-rc4-mm1/include/linux/mempolicy.h 2005-08-01 13:00:01.000000000 -0700
@@ -157,6 +157,10 @@
extern void numa_policy_init(void);
extern struct mempolicy default_policy;

+/* Conversion functions */
+int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol);
+struct mempolicy *str_to_mpol(char *buffer);
+
#else

struct mempolicy {};
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/