Skip to content

Commit

Permalink
Add cpu affinity and socket partitioning
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeroen Koekkoek authored and k0ekk0ek committed Jan 16, 2020
1 parent 99d709e commit ed585b1
Show file tree
Hide file tree
Showing 20 changed files with 1,137 additions and 56 deletions.
12 changes: 10 additions & 2 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ EDIT = sed \
TARGETS=nsd nsd-checkconf nsd-checkzone nsd-control nsd.conf.sample nsd-control-setup.sh
MANUALS=nsd.8 nsd-checkconf.8 nsd-checkzone.8 nsd-control.8 nsd.conf.5

COMMON_OBJ=answer.o axfr.o buffer.o configlexer.o configparser.o dname.o dns.o edns.o iterated_hash.o lookup3.o namedb.o nsec3.o options.o packet.o query.o rbtree.o radtree.o rdata.o region-allocator.o rrl.o tsig.o tsig-openssl.o udb.o udbradtree.o udbzone.o util.o
COMMON_OBJ=answer.o axfr.o buffer.o configlexer.o configparser.o dname.o dns.o edns.o iterated_hash.o lookup3.o namedb.o nsec3.o options.o packet.o query.o rbtree.o radtree.o rdata.o region-allocator.o rrl.o tsig.o tsig-openssl.o udb.o udbradtree.o udbzone.o util.o bitset.o
XFRD_OBJ=xfrd-disk.o xfrd-notify.o xfrd-tcp.o xfrd.o remote.o $(DNSTAP_OBJ)
NSD_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) difffile.o ipc.o mini_event.o netio.o nsd.o server.o dbaccess.o dbcreate.o zlexer.o zonec.o zparser.o
ALL_OBJ=$(NSD_OBJ) nsd-checkconf.o nsd-checkzone.o nsd-control.o nsd-mem.o
NSD_CHECKCONF_OBJ=$(COMMON_OBJ) nsd-checkconf.o
NSD_CHECKZONE_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o zonec.o zparser.o zlexer.o nsd-checkzone.o
NSD_CONTROL_OBJ=$(COMMON_OBJ) nsd-control.o
CUTEST_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o zonec.o zparser.o zlexer.o cutest_dname.o cutest_dns.o cutest_iterated_hash.o cutest_run.o cutest_radtree.o cutest_rbtree.o cutest_namedb.o cutest_options.o cutest_region.o cutest_rrl.o cutest_udb.o cutest_udbrad.o cutest_util.o cutest.o qtest.o
CUTEST_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o zonec.o zparser.o zlexer.o cutest_dname.o cutest_dns.o cutest_iterated_hash.o cutest_run.o cutest_radtree.o cutest_rbtree.o cutest_namedb.o cutest_options.o cutest_region.o cutest_rrl.o cutest_udb.o cutest_udbrad.o cutest_util.o cutest_bitset.o cutest.o qtest.o
NSD_MEM_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o zonec.o zparser.o zlexer.o nsd-mem.o
all: $(TARGETS) $(MANUALS)

Expand Down Expand Up @@ -243,6 +243,9 @@ reallocarray.o: $(srcdir)/compat/reallocarray.c
fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c
$(COMPILE) -c $(srcdir)/compat/fake-rfc2553.c

cpuset.o: $(srcdir)/compat/cpuset.c
$(COMPILE) -c $(srcdir)/compat/cpuset.c

cutest_dname.o: $(srcdir)/tpkg/cutest/cutest_dname.c
$(COMPILE) -c $(srcdir)/tpkg/cutest/cutest_dname.c

Expand Down Expand Up @@ -282,6 +285,9 @@ cutest_udbrad.o: $(srcdir)/tpkg/cutest/cutest_udbrad.c
cutest_util.o: $(srcdir)/tpkg/cutest/cutest_util.c
$(COMPILE) -c $(srcdir)/tpkg/cutest/cutest_util.c

cutest_bitset.o: $(srcdir)/tpkg/cutest/cutest_bitset.c
$(COMPILE) -c $(srcdir)/tpkg/cutest/cutest_bitset.c

cutest.o: $(srcdir)/tpkg/cutest/cutest.c
$(COMPILE) -c $(srcdir)/tpkg/cutest/cutest.c

Expand Down Expand Up @@ -462,6 +468,7 @@ udbzone.o: $(srcdir)/udbzone.c config.h $(srcdir)/udbzone.h $(srcdir)/udb.h $(sr
$(srcdir)/namedb.h $(srcdir)/radtree.h $(srcdir)/options.h
util.o: $(srcdir)/util.c config.h $(srcdir)/util.h $(srcdir)/region-allocator.h $(srcdir)/dname.h $(srcdir)/buffer.h \
$(srcdir)/namedb.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/rdata.h $(srcdir)/zonec.h
bitset.o: $(srcdir)/bitset.c $(srcdir)/bitset.h
xfrd.o: $(srcdir)/xfrd.c config.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h $(srcdir)/region-allocator.h $(srcdir)/namedb.h \
$(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/xfrd-tcp.h \
$(srcdir)/xfrd-disk.h $(srcdir)/xfrd-notify.h $(srcdir)/netio.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/rdata.h \
Expand Down Expand Up @@ -489,6 +496,7 @@ b64_ntop.o: $(srcdir)/compat/b64_ntop.c config.h
b64_pton.o: $(srcdir)/compat/b64_pton.c config.h
basename.o: $(srcdir)/compat/basename.c
fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c $(srcdir)/compat/fake-rfc2553.h config.h
cpuset.o: $(srcdir)/compat/cpuset.c $(srcdir)/compat/cpuset.h config.h
inet_aton.o: $(srcdir)/compat/inet_aton.c config.h
inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h
inet_pton.o: $(srcdir)/compat/inet_pton.c config.h
Expand Down
109 changes: 109 additions & 0 deletions bitset.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* bitset.h -- Dynamic bitset.
*
* Copyright (c) 2001-2020, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
*/
#include "config.h"
#include "bitset.h"

#include <assert.h>
#include <limits.h>
#include <string.h>

size_t nsd_bitset_size(size_t bits)
{
if(bits == 0)
bits++;

return (bits / CHAR_BIT) + ((bits % CHAR_BIT) != 0) + sizeof(size_t);
}

void nsd_bitset_zero(struct nsd_bitset *bset)
{
size_t sz;

assert(bset != NULL);

sz = nsd_bitset_size(bset->size) - sizeof(bset->size);
assert(sz > 0);
memset(bset->bits, 0, sz);
}

void nsd_bitset_init(struct nsd_bitset *bset, size_t bits)
{
assert(bset != NULL);
if (bits == 0)
bits++;

bset->size = bits;
nsd_bitset_zero(bset);
}

int nsd_bitset_isset(struct nsd_bitset *bset, size_t bit)
{
assert(bset != NULL);
if(bit >= bset->size)
return 0;

return (bset->bits[ (bit / CHAR_BIT) ] & (1 << (bit % CHAR_BIT))) != 0;
}

void nsd_bitset_set(struct nsd_bitset *bset, size_t bit)
{
assert(bset != NULL);
assert(bset->size > bit);
bset->bits[ (bit / CHAR_BIT) ] |= (1 << (bit % CHAR_BIT));
}

void nsd_bitset_unset(struct nsd_bitset *bset, size_t bit)
{
assert(bset != NULL);
assert(bset->size > bit);
bset->bits[ (bit / CHAR_BIT) ] &= ~(1 << (bit % CHAR_BIT));
}

void nsd_bitset_or(
struct nsd_bitset *destset,
struct nsd_bitset *srcset1,
struct nsd_bitset *srcset2)
{
size_t i, n, size, bytes;
unsigned char bits;
unsigned int mask;

assert(destset != NULL);
assert(srcset1 != NULL);
assert(srcset2 != NULL);

size = destset->size;
bytes = (size / CHAR_BIT) + ((size % CHAR_BIT) != 0);

for(i = 0; i < bytes; i++) {
bits = 0;

n = (srcset1->size / CHAR_BIT);
if (n > i) {
bits |= srcset1->bits[i];
} else {
n += ((srcset1->size % CHAR_BIT) != 0);
mask = (1 << ((srcset1->size % CHAR_BIT) + 1)) - 1;
if (n > i) {
bits |= (srcset1->bits[i] & mask);
}
}
n = (srcset2->size / CHAR_BIT);
if (n > i) {
bits |= srcset2->bits[i];
} else {
n += ((srcset2->size % CHAR_BIT) != 0);
mask = (1 << ((srcset2->size % CHAR_BIT) + 1)) - 1;
if (n > i) {
bits |= (srcset2->bits[i] & mask);
}
}
destset->bits[i] = bits;
}
}
40 changes: 40 additions & 0 deletions bitset.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* bitset.h -- Dynamic bitset.
*
* Copyright (c) 2001-2020, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
*/
#ifndef _BITSET_H_
#define _BITSET_H_

#include <assert.h>
#include <limits.h>
#include <string.h>

typedef struct nsd_bitset nsd_bitset_type;

struct nsd_bitset {
size_t size; /** Number of available bits in the set */
unsigned char bits[];
};

size_t nsd_bitset_size(size_t bits);

void nsd_bitset_zero(struct nsd_bitset *bset);

void nsd_bitset_init(struct nsd_bitset *bset, size_t bits);

int nsd_bitset_isset(struct nsd_bitset *bset, size_t bit);

void nsd_bitset_set(struct nsd_bitset *bset, size_t bit);

void nsd_bitset_unset(struct nsd_bitset *bset, size_t bit);

void nsd_bitset_or(
struct nsd_bitset *destset,
struct nsd_bitset *srcset1,
struct nsd_bitset *srcset2);

#endif /* _BITSET_H_ */
92 changes: 92 additions & 0 deletions compat/cpuset.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* cpuset.c -- CPU affinity.
*
* Copyright (c) 2020, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
*/
#include "cpuset.h"

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#ifndef HAVE_CPUSET_CREATE
#if __linux__ || __FreeBSD__
cpuset_t *cpuset_create(void)
{
cpuset_t *set = calloc(1, sizeof(*set));
return set;
}
#endif
#endif /* !HAVE_CPUSET_CREATE */

#ifndef HAVE_CPUSET_DESTROY
#if __linux__ || __FreeBSD__
void cpuset_destroy(cpuset_t *set)
{
free(set);
}
#endif
#endif /* !HAVE_CPUSET_DESTROY */

#ifndef HAVE_CPUSET_ZERO
#if __linux__ || __FreeBSD__
void cpuset_zero(cpuset_t *set)
{
CPU_ZERO(set);
}
#endif
#endif /* !HAVE_CPUSET_ZERO */

#ifndef HAVE_CPUSET_SET
#if __linux__ || __FreeBSD__
int cpuset_set(cpuid_t cpu, cpuset_t *set)
{
CPU_SET(cpu, set);
return 0;
}
#endif
#endif /* !HAVE_CPUSET_SET */

#ifndef HAVE_CPUSET_CLR
#if __linux__ || __FreeBSD__
int cpuset_clr(cpuid_t cpu, cpuset_t *set)
{
CPU_CLR(cpu, set);
return 0;
}
#endif
#endif /* !HAVE_CPUSET_CLR */

#ifndef HAVE_CPUSET_ISSET
#if __linux__ || __FreeBSD__
int cpuset_isset(cpuid_t cpu, const cpuset_t *set)
{
return CPU_ISSET(cpu, set);
}
#endif
#endif /* !HAVE_CPUSET_ISSET */

#ifndef HAVE_CPUSET_SIZE
#if __linux__ || __FreeBSD__
size_t cpuset_size(const cpuset_t *set)
{
return sizeof(*set);
}
#endif
#endif /* !HAVE_CPUSET_SIZE */

#if __linux__
void cpuset_or(cpuset_t *destset, const cpuset_t *srcset)
{
CPU_OR(destset, destset, srcset);
}
#endif
#if __FreeBSD__
void cpuset_or(cpuset_t *destset, const cpuset_t *srcset)
{
CPU_OR(destset, srcset);
}
#endif
79 changes: 79 additions & 0 deletions compat/cpuset.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* cpuset.h -- CPU affinity.
*
* Copyright (c) 2020, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
*/
#ifndef _CPUSET_H_
#define _CPUSET_H_
#include "config.h"

#ifdef HAVE_SCHED_H
# include <sched.h>
#endif

#ifdef HAVE_SYS_CPUSET_H
# include <sys/cpuset.h>
#endif

/*
* CPU affinity is currently only supported on Linux and FreeBSD. Other
* operating systems may be supported in the future, but not all operating
* systems offer the same functionality. OpenBSD for example does not support
* any kind of CPU affinity, while Solaris offers specifying a set of
* processors, but a processor can only be part of a single set.
*
* NOTE: On macOS Mojave, processor_set_create returned KERN_FAILURE which
* indicates processor allocation is not supported by the operating
* system.
*/

#ifndef HAVE_CPUSET_T
#ifdef HAVE_CPU_SET_T
#define HAVE_CPUSET_T 1
typedef cpu_set_t cpuset_t;
#endif
#endif

#ifndef HAVE_CPUID_T
#ifdef __linux__
typedef int cpuid_t;
#endif
#ifdef __FreeBSD__
typedef size_t cpuid_t;
#endif
#endif

#ifndef HAVE_CPUSET_CREATE
cpuset_t *cpuset_create(void);
#endif

#ifndef HAVE_CPUSET_DESTROY
void cpuset_destroy(cpuset_t *set);
#endif

#ifndef HAVE_CPUSET_ZERO
void cpuset_zero(cpuset_t *set);
#endif

#ifndef HAVE_CPUSET_SET
int cpuset_set(cpuid_t cpu, cpuset_t *set);
#endif

#ifndef HAVE_CPUSET_CLR
int cpuset_clr(cpuid_t cpu, cpuset_t *set);
#endif

#ifndef HAVE_CPUSET_ISSET
int cpuset_isset(cpuid_t cpu, const cpuset_t *set);
#endif

#ifndef HAVE_CPUSET_SIZE
size_t cpuset_size(const cpuset_t *set);
#endif

void cpuset_or(cpuset_t *destset, const cpuset_t *srcset);

#endif /* _CPUSET_H_ */
Loading

0 comments on commit ed585b1

Please sign in to comment.