Example #1
0
static char * _memset_to_str(nodemask_t *mask, char *str)
{
	int base, begin = 0;
	char *ptr = str;
	char *ret = 0;

	for (base = NUMA_NUM_NODES - 4; base >= 0; base -= 4) {
		char val = 0;
		if (nodemask_isset(mask, base))
			val |= 1;
		if (nodemask_isset(mask, base + 1))
			val |= 2;
		if (nodemask_isset(mask, base + 2))
			val |= 4;
		if (nodemask_isset(mask, base + 3))
			val |= 8;
		if ((begin == 0) && (val == 0) && (base > 124)) {
			/* try to keep output to 32 bit mask */
			continue;
		}
		begin = 1;
		if (!ret && val)
			ret = ptr;
		*ptr++ = val_to_char(val);
	}
	*ptr = 0;
	return ret ? ret : ptr - 1;
}
Example #2
0
static int filter_nodemask_mem(nodemask_t * nodemask, unsigned long max_node)
{
#if MPOL_F_MEMS_ALLOWED
	unsigned long nodemask_size = max_node / 8 + 1;
	memset(nodemask, 0, nodemask_size);
	/*
	 * avoid numa_get_mems_allowed(), because of bug in getpol()
	 * utility function in older versions:
	 * http://www.spinics.net/lists/linux-numa/msg00849.html
	 */
	if (ltp_syscall(__NR_get_mempolicy, NULL, nodemask->n,
		    max_node, 0, MPOL_F_MEMS_ALLOWED) < 0)
		return -2;
#else
	int i;
	/*
	 * old libnuma/kernel don't have MPOL_F_MEMS_ALLOWED, so let's assume
	 * that we can use any node with memory > 0
	 */
	for (i = 0; i < max_node; i++) {
		if (!nodemask_isset(nodemask, i))
			continue;
		if (numa_node_size64(i, NULL) <= 0)
			nodemask_clr(nodemask, i);
	}
#endif /* MPOL_F_MEMS_ALLOWED */
	return 0;
}
Example #3
0
File: commands.c Project: 1587/ltp
/*
 * get_current_nodeid_list() - fill arg array with nodes from
 * current thread's allowed node mask.  return # of nodes in
 * mask.
 */
static int get_current_nodeid_list(unsigned int *fromids)
{
	/*
	 * FIXME (garrcoop): gcp is unitialized and shortly hereafter used in
	 * an initialization statement..... UHHHHHHH... test writer fail?
	 */
	glctx_t *gcp;
	nodemask_t my_allowed_nodes;
	int nr_nodes = 0, max_node = gcp->numa_max_node;
	int node;

	gcp = &glctx;
#if defined(LIBNUMA_API_VERSION) && LIBNUMA_API_VERSION == 2
	my_allowed_nodes = numa_get_membind_compat();
#else
	my_allowed_nodes = numa_get_membind();
#endif
	for (node = 0; node <= max_node; ++node) {
		if (nodemask_isset(&my_allowed_nodes, node))
			*(fromids + nr_nodes++) = node;
	}

	/*
	 * shouldn't happen, but let 'em know if it does
	 */
	if (nr_nodes == 0)
		fprintf(stderr, "%s:  my allowed node mask is empty !!???\n",
			gcp->program_name);
	return nr_nodes;
}
Example #4
0
File: cpuset.c Project: IFCA/slurm
int	slurm_set_memset(char *path, nodemask_t *new_mask)
{
	char file_path[PATH_MAX];
	char mstr[1 + CPU_SETSIZE * 4], tmp[10];
	int fd, i, max_node;
	ssize_t rc;

	snprintf(file_path, sizeof(file_path), "%s/mems", path);
	fd = open(file_path, O_CREAT | O_RDWR, 0700);
	if (fd < 0) {
		error("open(%s): %m", file_path);
		return -1;
	}

	mstr[0] = '\0';
	max_node = numa_max_node();
	for (i=0; i<=max_node; i++) {
		if (!nodemask_isset(new_mask, i))
			continue;
		snprintf(tmp, sizeof(tmp), "%d", i);
		if (mstr[0])
			strcat(mstr, ",");
		strcat(mstr, tmp);
	}

	i = strlen(mstr) + 1;
	rc = write(fd, mstr, i+1);
	close(fd);
	if (rc <= i) {
		error("write(%s): %m", file_path);
		return -1;
	}
	return 0;
}
static void _numa_set_preferred(nodemask_t *new_mask)
{
	int i;

	for (i = 0; i < NUMA_NUM_NODES; i++) {
		if (nodemask_isset(new_mask, i)) {
			numa_set_preferred(i);
			break;
		}
	}
}
Example #6
0
File: commands.c Project: 1587/ltp
/*
 * get_arg_nodeid_list() -- get list [array] of node ids from comma-separated list.
 *
 * on success, returns count of id's in list; on error -1
 */
static int get_arg_nodeid_list(char *args, unsigned int *list)
{
	glctx_t *gcp;
	char *next;
	nodemask_t my_allowed_nodes;
	int node, count = 0;

	gcp = &glctx;
#if defined(LIBNUMA_API_VERSION) && LIBNUMA_API_VERSION == 2
	my_allowed_nodes = numa_get_membind_compat();
#else
	my_allowed_nodes = numa_get_membind();
#endif
	while (*args != '\0') {
		if (!isdigit(*args)) {
			fprintf(stderr, "%s:  expected digit for <node/list>\n",
				gcp->program_name);
			return -1;
		}

		node = strtoul(args, &next, 10);

		if (node > gcp->numa_max_node) {
			fprintf(stderr, "%s:  node ids must be <= %d\n",
				gcp->program_name, gcp->numa_max_node);
			return -1;
		}

		if (!nodemask_isset(&my_allowed_nodes, node)) {
			fprintf(stderr,
				"%s:  node %d is not in my allowed node mask\n",
				gcp->program_name, node);
			return -1;
		}

		*(list + count++) = node;

		if (*next == '\0')
			return count;
		if (*next != ',') {
			break;
		}

		if (count >= gcp->numa_max_node) {
			fprintf(stderr, "%s:  too many node ids in list\n",
				gcp->program_name);
		}
		args = next + 1;
	}

	return -1;
}
Example #7
0
/*
 * get_allowed_nodes_arr - get number and array of available nodes
 * @num_nodes: pointer where number of available nodes will be stored
 * @nodes: array of available node ids, this is MPOL_F_MEMS_ALLOWED
 *                 node bitmask compacted (without holes), so that each field
 *                 contains node number. If NULL only num_nodes is
 *                 returned, otherwise it cotains new allocated array,
 *                 which caller is responsible to free.
 * RETURNS:
 *     0 on success
 *    -1 on allocation failure
 *    -2 on get_mempolicy failure
 */
int get_allowed_nodes_arr(int flag, int *num_nodes, int **nodes)
{
	int ret = 0;
#if HAVE_NUMA_H
	int i;
	nodemask_t *nodemask = NULL;
#endif
	*num_nodes = 0;
	if (nodes)
		*nodes = NULL;

#if HAVE_NUMA_H
	unsigned long max_node = LTP_ALIGN(get_max_node(),
						sizeof(unsigned long)*8);
	unsigned long nodemask_size = max_node / 8;

	nodemask = malloc(nodemask_size);
	if (nodes)
		*nodes = malloc(sizeof(int) * max_node);

	do {
		if (nodemask == NULL || (nodes && (*nodes == NULL))) {
			ret = -1;
			break;
		}

		/* allow all nodes at start, then filter based on flags */
		get_nodemask_allnodes(nodemask, max_node);
		if ((flag & NH_MEMS) == NH_MEMS) {
			ret = filter_nodemask_mem(nodemask, max_node);
			if (ret < 0)
				break;
		}
		if ((flag & NH_CPUS) == NH_CPUS)
			filter_nodemask_cpu(nodemask, max_node);

		for (i = 0; i < max_node; i++) {
			if (nodemask_isset(nodemask, i)) {
				if (nodes)
					(*nodes)[*num_nodes] = i;
				(*num_nodes)++;
			}
		}
	} while (0);
	free(nodemask);
#endif
	return ret;
}
Example #8
0
static void filter_nodemask_cpu(nodemask_t * nodemask, unsigned long max_node)
{
	char *cpumask = NULL;
	char fn[64];
	FILE *f;
	size_t len;
	int i, ret;

	for (i = 0; i < max_node; i++) {
		if (!nodemask_isset(nodemask, i))
			continue;
		sprintf(fn, "/sys/devices/system/node/node%d/cpumap", i);
		f = fopen(fn, "r");
		if (f) {
			ret = getdelim(&cpumask, &len, '\n', f);
			if ((ret > 0) && (!cpumask_has_cpus(cpumask, len)))
				nodemask_clr(nodemask, i);
			fclose(f);
		}
	}
	free(cpumask);
}
Example #9
0
int
virNumaSetupMemoryPolicy(virDomainNumatuneMemMode mode,
                         virBitmapPtr nodeset)
{
    nodemask_t mask;
    int node = -1;
    int ret = -1;
    int bit = 0;
    size_t i;
    int maxnode = 0;

    if (!nodeset)
        return 0;

    if (!virNumaNodesetIsAvailable(nodeset))
        return -1;

    maxnode = numa_max_node();
    maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;

    /* Convert nodemask to NUMA bitmask. */
    nodemask_zero(&mask);
    bit = -1;
    while ((bit = virBitmapNextSetBit(nodeset, bit)) >= 0) {
        if (bit > maxnode) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("NUMA node %d is out of range"), bit);
            return -1;
        }
        nodemask_set(&mask, bit);
    }

    switch (mode) {
    case VIR_DOMAIN_NUMATUNE_MEM_STRICT:
        numa_set_bind_policy(1);
        numa_set_membind(&mask);
        numa_set_bind_policy(0);
        break;

    case VIR_DOMAIN_NUMATUNE_MEM_PREFERRED:
    {
        int nnodes = 0;
        for (i = 0; i < NUMA_NUM_NODES; i++) {
            if (nodemask_isset(&mask, i)) {
                node = i;
                nnodes++;
            }
        }

        if (nnodes != 1) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("NUMA memory tuning in 'preferred' mode "
                                   "only supports single node"));
            goto cleanup;
        }

        numa_set_bind_policy(0);
        numa_set_preferred(node);
    }
    break;

    case VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE:
        numa_set_interleave_mask(&mask);
        break;

    case VIR_DOMAIN_NUMATUNE_MEM_LAST:
        break;
    }
    ret = 0;

cleanup:
    return ret;
}
Example #10
0
int
virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
                         virBitmapPtr nodemask)
{
    nodemask_t mask;
    int mode = -1;
    int node = -1;
    int ret = -1;
    int i = 0;
    int maxnode = 0;
    virBitmapPtr tmp_nodemask = NULL;

    if (numatune.memory.placement_mode ==
        VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC) {
        if (!numatune.memory.nodemask)
            return 0;
        VIR_DEBUG("Set NUMA memory policy with specified nodeset");
        tmp_nodemask = numatune.memory.nodemask;
    } else if (numatune.memory.placement_mode ==
               VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) {
        VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
        tmp_nodemask = nodemask;
    } else {
        return 0;
    }

    if (numa_available() < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("Host kernel is not aware of NUMA."));
        return -1;
    }

    maxnode = numa_max_node() + 1;

    /* Convert nodemask to NUMA bitmask. */
    nodemask_zero(&mask);
    i = -1;
    while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
        if (i > maxnode || i > NUMA_NUM_NODES) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Nodeset is out of range, host cannot support "
                             "NUMA node bigger than %d"), i);
            return -1;
        }
        nodemask_set(&mask, i);
    }

    mode = numatune.memory.mode;

    if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
        numa_set_bind_policy(1);
        numa_set_membind(&mask);
        numa_set_bind_policy(0);
    } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
        int nnodes = 0;
        for (i = 0; i < NUMA_NUM_NODES; i++) {
            if (nodemask_isset(&mask, i)) {
                node = i;
                nnodes++;
            }
        }

        if (nnodes != 1) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("NUMA memory tuning in 'preferred' mode "
                                   "only supports single node"));
            goto cleanup;
        }

        numa_set_bind_policy(0);
        numa_set_preferred(node);
    } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
        numa_set_interleave_mask(&mask);
    } else {
        /* XXX: Shouldn't go here, as we already do checking when
         * parsing domain XML.
         */
        virReportError(VIR_ERR_XML_ERROR,
                       "%s", _("Invalid mode for memory NUMA tuning."));
        goto cleanup;
    }

    ret = 0;

cleanup:
    return ret;
}
Example #11
0
static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl)
{
    nodemask_t mask;
    int mode = -1;
    int node = -1;
    int ret = -1;
    int i = 0;
    int maxnode = 0;
    bool warned = false;

    if (!ctrl->def->numatune.memory.nodemask)
        return 0;

    VIR_DEBUG("Setting NUMA memory policy");

    if (numa_available() < 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       "%s", _("Host kernel is not aware of NUMA."));
        return -1;
    }

    maxnode = numa_max_node() + 1;

    /* Convert nodemask to NUMA bitmask. */
    nodemask_zero(&mask);
    i = -1;
    while ((i = virBitmapNextSetBit(ctrl->def->numatune.memory.nodemask, i)) >= 0) {
        if (i > NUMA_NUM_NODES) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Host cannot support NUMA node %d"), i);
            return -1;
        }
        if (i > maxnode && !warned) {
            VIR_WARN("nodeset is out of range, there is only %d NUMA "
                     "nodes on host", maxnode);
            warned = true;
        }
        nodemask_set(&mask, i);
    }

    mode = ctrl->def->numatune.memory.mode;

    if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
        numa_set_bind_policy(1);
        numa_set_membind(&mask);
        numa_set_bind_policy(0);
    } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
        int nnodes = 0;
        for (i = 0; i < NUMA_NUM_NODES; i++) {
            if (nodemask_isset(&mask, i)) {
                node = i;
                nnodes++;
            }
        }

        if (nnodes != 1) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("NUMA memory tuning in 'preferred' mode "
                                   "only supports single node"));
            goto cleanup;
        }

        numa_set_bind_policy(0);
        numa_set_preferred(node);
    } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
        numa_set_interleave_mask(&mask);
    } else {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Unable to set NUMA policy %s"),
                       virDomainNumatuneMemModeTypeToString(mode));
        goto cleanup;
    }

    ret = 0;

cleanup:
    return ret;
}