public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] String conversions for memory policy
@ 2005-07-29 18:38 Christoph Lameter
  2005-07-29 22:20 ` Paul Jackson
  0 siblings, 1 reply; 44+ messages in thread
From: Christoph Lameter @ 2005-07-29 18:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: akpm, pj

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 <christoph@lameter.com>

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 {};

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2005-08-05 15:03 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-29 18:38 [PATCH] String conversions for memory policy Christoph Lameter
2005-07-29 22:20 ` Paul Jackson
2005-07-30  0:53   ` Christoph Lameter
2005-07-30  5:54     ` Paul Jackson
2005-07-30 15:48       ` Christoph Lameter
2005-07-31  1:45         ` Paul Jackson
2005-07-30  6:00     ` Paul Jackson
2005-07-30 17:56       ` Christoph Lameter
2005-07-31  1:14         ` Paul Jackson
2005-07-31  1:21           ` Christoph Lameter
2005-07-31  1:50             ` Paul Jackson
2005-07-31  2:01             ` Paul Jackson
2005-07-31  2:05               ` Christoph Lameter
2005-07-31  2:12                 ` Paul Jackson
2005-07-31  2:15                   ` Christoph Lameter
2005-08-01 18:48                   ` Christoph Lameter
2005-08-01 18:54                     ` Christoph Lameter
2005-08-01 23:03                     ` Paul Jackson
2005-08-01 23:24                       ` Christoph Lameter
2005-08-01 23:59                         ` Paul Jackson
2005-08-02  0:03                           ` Christoph Lameter
2005-08-02  0:15                           ` Christoph Lameter
2005-08-02  5:33                             ` Paul Jackson
2005-08-02  6:11                               ` Christoph Lameter
2005-08-03  5:44                                 ` Paul Jackson
2005-08-03 16:19                                   ` Christoph Lameter
2005-08-02 17:49                               ` Christoph Lameter
2005-08-03  5:42                                 ` Paul Jackson
2005-08-03  8:48                     ` Andi Kleen
2005-08-04 14:11                       ` Christoph Lameter
2005-08-04 14:29                         ` Andi Kleen
2005-08-04 16:31                           ` Christoph Lameter
2005-08-04 17:08                             ` Andi Kleen
2005-08-04 17:34                               ` NUMA policy interface Christoph Lameter
2005-08-04 21:14                                 ` Andi Kleen
2005-08-04 21:21                                   ` Christoph Lameter
2005-08-04 21:41                                     ` Andi Kleen
2005-08-04 22:19                                       ` Christoph Lameter
2005-08-04 22:44                                         ` Mike Kravetz
2005-08-04 23:40                                         ` Andi Kleen
2005-08-04 23:49                                           ` Christoph Lameter
2005-08-05  9:16                                             ` Andi Kleen
2005-08-05 14:52                                               ` Christoph Lameter
2005-08-05 14:58                                               ` Christoph Lameter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox