Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add cpu bindings (cpumask option)

  • Loading branch information...
commit 9038767a2ba77bea465ab42527386481e384af01 1 parent b041a17
Vladimir Davydov authored kolyshkin committed
2  etc/bash_completion.d/vzctl.sh.in
View
@@ -60,7 +60,7 @@ _vzctl()
--dgramrcvbuf --oomguarpages --lockedpages --privvmpages \
--shmpages --numfile --numflock --numpty --numsiginfo \
--dcachesize --numiptent --physpages --swappages \
- --cpuunits --cpulimit --cpus \
+ --cpuunits --cpulimit --cpus --cpumask \
--iptables --netdev_add --netdev_del --netif_add --netif_del \
--diskquota \
--diskspace --diskinodes --quotatime --quotaugidlimit \
7 include/cpu.h
View
@@ -21,6 +21,12 @@
#define MAXCPUUNITS 500000
#define MINCPUUNITS 8
+#define CPUMASK_NBITS 1024
+typedef struct {
+ unsigned long bits[CPUMASK_NBITS / (8 * sizeof(unsigned long))];
+} cpumask_t;
+#define cpumask_bits(maskp) ((maskp)->bits)
+
/** Data structure for cpu parameters.
*/
typedef struct {
@@ -28,6 +34,7 @@ typedef struct {
unsigned long *weight;
unsigned long *units; /**< CPU weight for the CT, in units. */
unsigned long *vcpus; /**< number of CPUs available in the running CT */
+ cpumask_t *mask; /**< CT's CPU affinity mask */
} cpu_param;
/** Apply cpu parameters on running CT.
1  include/vzctl_param.h
View
@@ -46,6 +46,7 @@
#define PARAM_CPULIMIT 15
#define PARAM_CPUUNITS 16
#define PARAM_VCPUS 17
+#define PARAM_CPUMASK 171
#define PARAM_IP_ADD 18
#define PARAM_IP_DEL 19
2  include/vzsyscalls.h
View
@@ -28,6 +28,7 @@
#define __NR_setublimit 1507
#define __NR_ioprio_set 1274
#elif __x86_64__
+#define __NR_fairsched_cpumask 498
#define __NR_fairsched_vcpus 499
#define __NR_setluid 501
#define __NR_setublimit 502
@@ -45,6 +46,7 @@
#define __NR_fairsched_chwt 502
#define __NR_fairsched_rate 504
#define __NR_fairsched_vcpus 505
+#define __NR_fairsched_cpumask 506
#define __NR_setluid 511
#define __NR_setublimit 512
#ifdef __sparc__
9 man/vzctl.8
View
@@ -367,6 +367,15 @@ limit is \fB0\fR (no CPU limit).
.TP
\fB--cpus\fR \fInum\fR
sets number of CPUs available in the container.
+.TP
+\fB--cpumask\fR \fIcpus\fR | \fBall\fR
+sets list of allowed CPUs for the container.
+Input format is a comma-separated list of decimal numbers and ranges.
+Consecutively set bits are shown as two hyphen-separated decimal numbers,
+the smallest and largest bit numbers set in the range.
+For example, if you want the container to execute on CPUs 0, 1, 2, 7,
+you should pass \fB0-2,7\fR.
+Default value is \fBall\fR (the container can execute on any CPU).
.TP
\fBMemory output parameters\fR
3  src/lib/Makefile.am
View
@@ -27,7 +27,8 @@ LIB_VER = 0.0.3
lib_LTLIBRARIES = libvzctl.la
-libvzctl_la_SOURCES = cap.c \
+libvzctl_la_SOURCES = bitmap.c \
+ cap.c \
config.c \
cpt.c \
cpu.c \
68 src/lib/config.c
View
@@ -36,6 +36,7 @@
#include "logger.h"
#include "list.h"
+#include "bitmap.h"
#include "config.h"
#include "vzctl_param.h"
#include "vzerror.h"
@@ -118,6 +119,7 @@ static vps_config config[] = {
{"CPUUWEIGHT", NULL, PARAM_CPUWEIGHT},
{"CPULIMIT", NULL, PARAM_CPULIMIT},
{"CPUS", NULL, PARAM_VCPUS},
+{"CPUMASK", NULL, PARAM_CPUMASK},
/* create param */
{"ONBOOT", NULL, PARAM_ONBOOT},
{"CONFIGFILE", NULL, PARAM_CONFIG},
@@ -252,6 +254,28 @@ static int conf_parse_ulong(unsigned long **dst, const char *valstr)
return 0;
}
+static int conf_parse_bitmap(unsigned long **dst, int nmaskbits,
+ const char *valstr)
+{
+ if (*dst != NULL)
+ return ERR_DUP;
+
+ *dst = alloc_bitmap(nmaskbits);
+ if (*dst == NULL)
+ return ERR_NOMEM;
+
+ if (!strcmp(valstr, "all")) {
+ bitmap_set_all(*dst, nmaskbits);
+ return 0;
+ }
+ if (bitmap_parse(valstr, *dst, nmaskbits) != 0) {
+ free(*dst);
+ *dst = NULL;
+ return ERR_INVAL;
+ }
+ return 0;
+}
+
static int conf_store_strlist(list_head_t *conf, char *name, list_head_t *val,
int allow_empty)
{
@@ -303,6 +327,32 @@ static int conf_store_ulong(list_head_t *conf, char *name, unsigned long *val)
return conf_store_str(conf, name, buf);
}
+static int conf_store_bitmap(list_head_t *conf, char *name,
+ unsigned long *val, int nmaskbits)
+{
+ int ret;
+ char *buf;
+ unsigned int buflen = nmaskbits * 2;
+
+ if (val == NULL)
+ return 0;
+
+ if (bitmap_find_first_zero_bit(val, nmaskbits) == nmaskbits) {
+ conf_store_str(conf, name, "all");
+ return 0;
+ }
+
+ buf = malloc(buflen);
+ if (buf == NULL)
+ return ERR_NOMEM;
+
+ bitmap_snprintf(buf, buflen, val, nmaskbits);
+ ret = conf_store_str(conf, name, buf);
+
+ free(buf);
+ return ret;
+}
+
/******************** Features *************************/
static int parse_features(env_param_t *env, char *val)
{
@@ -1251,6 +1301,16 @@ static int parse_cpulimit(unsigned long **param, const char *str)
return 0;
}
+static inline int parse_cpumask(cpumask_t **dst, const char *str)
+{
+ return conf_parse_bitmap((unsigned long **)dst, CPUMASK_NBITS, str);
+}
+
+static inline int store_cpumask(list_head_t *conf, char *name, cpumask_t *val)
+{
+ return conf_store_bitmap(conf, name, cpumask_bits(val), CPUMASK_NBITS);
+}
+
static int store_cpu(vps_param *old_p, vps_param *vps_p, vps_config *conf,
list_head_t *conf_h)
{
@@ -1269,6 +1329,9 @@ static int store_cpu(vps_param *old_p, vps_param *vps_p, vps_config *conf,
case PARAM_VCPUS:
conf_store_ulong(conf_h, conf->name, cpu->vcpus);
break;
+ case PARAM_CPUMASK:
+ store_cpumask(conf_h, conf->name, cpu->mask);
+ break;
}
return 0;
}
@@ -1934,6 +1997,9 @@ static int parse(envid_t veid, vps_param *vps_p, char *val, int id)
case PARAM_VCPUS:
ret = conf_parse_ulong(&vps_p->res.cpu.vcpus, val);
break;
+ case PARAM_CPUMASK:
+ ret = parse_cpumask(&vps_p->res.cpu.mask, val);
+ break;
case PARAM_MEMINFO:
ret = parse_meminfo(&vps_p->res.meminfo, val);
break;
@@ -2463,6 +2529,7 @@ static void free_cpu(cpu_param *cpu)
FREE_P(cpu->weight)
FREE_P(cpu->limit)
FREE_P(cpu->vcpus)
+ FREE_P(cpu->mask);
}
static void free_dq(dq_param *dq)
@@ -2578,6 +2645,7 @@ static void merge_cpu(cpu_param *dst, cpu_param *src)
MERGE_P(weight)
MERGE_P(limit)
MERGE_P(vcpus)
+ MERGE_P(mask);
}
#define MERGE_LIST(x) \
44 src/lib/cpu.c
View
@@ -23,6 +23,7 @@
#include <errno.h>
#include "types.h"
+#include "bitmap.h"
#include "cpu.h"
#include "env.h"
#include "vzerror.h"
@@ -59,6 +60,29 @@ static inline int fairsched_vcpus(unsigned int id, unsigned vcpus)
return ret;
}
+#if defined(__i386__) || defined(__x86_64__)
+static inline int fairsched_cpumask(unsigned int id,
+ unsigned int masksize, unsigned long *mask)
+{
+ int ret;
+
+ ret = syscall(__NR_fairsched_cpumask, id, masksize, mask);
+ if (ret && errno == ENOSYS)
+ ret = 0;
+ return ret;
+}
+#else
+/*
+ * fairsched_cpumask is available only in vz kernels based on linux 2.6.32
+ * or later which do not support platforms different from x86.
+ */
+static inline int fairsched_cpumask(unsigned int id,
+ unsigned int masksize, unsigned long *mask)
+{
+ return ENOTSUP;
+}
+#endif
+
static int set_cpulimit(envid_t veid, unsigned int cpulimit)
{
unsigned cpulim1024 = (float)cpulimit * 1024 / 100;
@@ -98,6 +122,20 @@ static int set_cpuunits(envid_t veid, unsigned int cpuunits)
return ret;
}
+static int set_cpumask(envid_t veid, cpumask_t *mask)
+{
+ static char maskstr[CPUMASK_NBITS * 2];
+
+ bitmap_snprintf(maskstr, CPUMASK_NBITS * 2,
+ cpumask_bits(mask), CPUMASK_NBITS);
+ logger(0, 0, "Setting CPU mask: %s", maskstr);
+ if (fairsched_cpumask(veid, sizeof(cpumask_t), cpumask_bits(mask))) {
+ logger(-1, errno, "fairsched_cpumask");
+ return VZ_SETFSHD_ERROR;
+ }
+ return 0;
+}
+
/** Change number of CPUs available in the running CT.
*
* @param veid CT ID
@@ -142,7 +180,8 @@ int vps_set_cpu(vps_handler *h, envid_t veid, cpu_param *cpu)
if (cpu->limit == NULL &&
cpu->units == NULL &&
cpu->weight == NULL &&
- cpu->vcpus == NULL)
+ cpu->vcpus == NULL &&
+ cpu->mask == NULL)
{
return 0;
}
@@ -161,6 +200,9 @@ int vps_set_cpu(vps_handler *h, envid_t veid, cpu_param *cpu)
if (cpu->vcpus != NULL) {
ret = env_set_vcpus(veid, *cpu->vcpus);
}
+ if (cpu->mask != NULL) {
+ ret = set_cpumask(veid, cpu->mask);
+ }
return ret;
}
1  src/vzctl-actions.c
View
@@ -565,6 +565,7 @@ static int parse_set_opt(envid_t veid, int argc, char *argv[],
{"cpuweight", required_argument, NULL, PARAM_CPUWEIGHT},
{"cpulimit", required_argument, NULL, PARAM_CPULIMIT},
{"cpus", required_argument, NULL, PARAM_VCPUS},
+ {"cpumask", required_argument, NULL, PARAM_CPUMASK},
/* create param */
{"onboot", required_argument, NULL, PARAM_ONBOOT},
{"setmode", required_argument, NULL, PARAM_SETMODE},
3  src/vzctl.c
View
@@ -75,7 +75,8 @@ void usage(int rc)
" [--ipadd <addr>] [--ipdel <addr>|all] [--hostname <name>]\n"
" [--nameserver <addr>] [--searchdomain <name>]\n"
" [--onboot yes|no] [--bootorder <N>]\n"
-" [--userpasswd <user>:<passwd>] [--cpuunits <N>] [--cpulimit <N>] [--cpus <N>]\n"
+" [--userpasswd <user>:<passwd>]\n"
+" [--cpuunits <N>] [--cpulimit <N>] [--cpus <N>] [--cpumask <cpus>]\n"
" [--diskspace <soft>[:<hard>]] [--diskinodes <soft>[:<hard>]]\n"
" [--quotatime <N>] [--quotaugidlimit <N>]\n"
" [--noatime yes|no] [--capability <name>:on|off ...]\n"
Please sign in to comment.
Something went wrong with that request. Please try again.