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

The patch provides necessary functions for the merging of numa_maps into 
smap.

Signed-off-by: Christoph Lameter <[EMAIL PROTECTED]>

Index: linux-2.6.13-rc3-mm3/mm/mempolicy.c
===================================================================
--- linux-2.6.13-rc3-mm3.orig/mm/mempolicy.c    2005-07-29 10:37:26.000000000 
-0700
+++ linux-2.6.13-rc3-mm3/mm/mempolicy.c 2005-07-29 11:08:13.000000000 -0700
@@ -1170,3 +1170,214 @@
 {
        sys_set_mempolicy(MPOL_DEFAULT, NULL, 0);
 }
+
+/*
+ * Convert a mempolicy into a string.
+ * Returns the number of characters in buffer (if positive)
+ * or an error (negative)
+ */
+int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol)
+{
+       char *p = buffer;
+       char *e = buffer + maxlen;
+       int first = 1;
+       int node;
+       struct zone **z;
+
+       if (!pol || pol->policy == MPOL_DEFAULT) {
+               strcpy(buffer,"default");
+               return 7;
+       }
+
+       if (pol->policy == MPOL_PREFERRED) {
+               if (e < p + 8 /* fixed string size */ + 4 /* max len of node 
number */)
+                       return -ENOSPC;
+
+               sprintf(p, "prefer=%d", pol->v.preferred_node);
+               return strlen(buffer);
+
+       } else if (pol->policy == MPOL_BIND) {
+
+               if (e < p + 9 + 4)
+                       return -ENOSPC;
+
+               p+= sprintf(p, "bind={");
+
+               for (z = pol->v.zonelist->zones; *z ; *z++) {
+                       if (!first)
+                               *p++ = ',';
+                       else
+                               first = 0;
+                       if (e < p + 2 + 4 + strlen((*z)->name))
+                               return -ENOSPC;
+                       p += sprintf(p, "%d/%s", (*z)->zone_pgdat->node_id, 
(*z)->name);
+               }
+
+               *p++ = '}';
+               *p++ = 0;
+               return p-buffer;
+
+       } else if (pol->policy == MPOL_INTERLEAVE) {
+
+               if (e < p + 14 + 4)
+                       return -ENOSPC;
+
+               p += sprintf(p, "interleave={");
+
+               for_each_node(node)
+                       if (test_bit(node, pol->v.nodes)) {
+                               if (!first)
+                                       *p++ = ',';
+                               else
+                                       first = 0;
+                               if (e < p + 2 /* min bytes that follow */ + 4 
/* node number */)
+                                       return -ENOSPC;
+                               p += sprintf(p, "%d", node);
+                       }
+
+               *p++ = '}';
+               *p++ = 0;
+               return p-buffer;
+       }
+       BUG();
+       return -EFAULT;
+}
+
+/*
+ * Convert a representation of a memory policy from text
+ * form to binary.
+ *
+ * Returns either a memory policy or NULL for error.
+ */
+struct mempolicy *str_to_mpol(char *buffer, char **end)
+{
+       char *p;
+       struct mempolicy *pol;
+       int node;
+       size_t size;
+
+       if (strnicmp(buffer, "default", 7) == 0) {
+
+               *end = buffer + 7;
+               return &default_policy;
+
+       }
+
+       pol = __mpol_copy(&default_policy);
+       if (IS_ERR(pol))
+               return NULL;
+
+       if (strnicmp(buffer, "prefer=", 7) == 0) {
+
+               node = simple_strtoul(buffer + 7, &p, 10);
+               if (node >= MAX_NUMNODES || !node_online(node))
+                       goto out;
+
+               pol->policy = MPOL_PREFERRED;
+               pol->v.preferred_node = node;
+
+       } else if (strnicmp(buffer, "interleave={", 12) == 0) {
+
+               pol->policy = MPOL_INTERLEAVE;
+               p = buffer + 12;
+               bitmap_zero(pol->v.nodes, MAX_NUMNODES);
+
+               do {
+                       node = simple_strtoul(p, &p, 10);
+
+                       /* Check here for cpuset restrictions on nodes */
+                       if (node >= MAX_NUMNODES || !node_online(node))
+                               goto out;
+                       set_bit(node, pol->v.nodes);
+
+               } while (*p++ == ',');
+
+               if (p[-1] != '}' || bitmap_empty(pol->v.nodes, MAX_NUMNODES))
+                       goto out;
+
+       } else if (strnicmp(buffer, "bind={", 6) == 0) {
+
+               struct zonelist *zonelist = kmalloc(sizeof(struct zonelist), 
GFP_KERNEL);
+               struct zone **z = zonelist->zones;
+               struct zonelist *new;
+
+               pol->policy = MPOL_BIND;
+               p = buffer + 6;
+
+               do {
+                       pg_data_t *pgdat;
+                       struct zone *zone = NULL;
+
+                       node = simple_strtoul(p, &p, 10);
+
+                       /* Try to find the pgdat for the specified node */
+                       for_each_pgdat(pgdat) {
+                               if (pgdat->node_id == node) {
+                                       zone = pgdat->node_zones;
+                                       break;
+                               }
+                       }
+                       if (!zone || node >= MAX_NUMNODES || !node_online(node))
+                               goto bind_out;
+
+                       /*
+                        * If there is no zone specified then take the first
+                        * zone. Otherwise we need to look for a matching name
+                        */
+                       if (*p == '/') {
+                               char *start = ++p;
+                               struct zone *q;
+                               struct zone *found = NULL;
+
+                               /* Find end of the zone name */
+                               while (*p && *p != ',' && *p != '}')
+                                       p++;
+
+                               if (start == p)
+                                       goto bind_out;
+                               /*
+                                * Go through the zones in this node and check
+                                * if any have the name we are looking for
+                                */
+                               for(q = zone; q < zone + MAX_NR_ZONES; q++) {
+                                       if (strnicmp(q->name, start, p-start) 
== 0) {
+                                               found = q;
+                                               break;
+                                       }
+                               }
+                               zone = found;
+                       }
+
+                       if (!zone || z > zonelist->zones + MAX_NUMNODES * 
MAX_NR_ZONES)
+                               goto bind_out;
+                       *z++ = zone;
+
+               } while (*p++ == ',');
+
+               if (p[-1] != '}') {
+bind_out:
+                       kfree(zonelist);
+                       goto out;
+               }
+
+               /* Allocate only the necessary elements */
+               *z++ = NULL;
+               size = (z - zonelist->zones) * sizeof(struct zonelist *);
+               new = kmalloc(size, GFP_KERNEL);
+               if (!new)
+                       goto out;
+               memcpy(new, zonelist, size);
+               kfree(zonelist);
+
+               pol->v.zonelist = new;
+
+       } else {
+out:
+               __mpol_free(pol);
+               return NULL;
+       }
+
+       *end = p;
+       return pol;
+}
+
Index: linux-2.6.13-rc3-mm3/include/linux/mempolicy.h
===================================================================
--- linux-2.6.13-rc3-mm3.orig/include/linux/mempolicy.h 2005-07-29 
10:37:26.000000000 -0700
+++ linux-2.6.13-rc3-mm3/include/linux/mempolicy.h      2005-07-29 
11:08:13.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, char **end);
+
 #else
 
 struct mempolicy {};
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to