Skip to content

Commit 5c93aa5

Browse files
author
Octavian Purdila
authored
Merge pull request torvalds#177 from liuyuan10/pin
lkl: Add LKL_HIJACK_SINGLE_CPU
2 parents d171188 + 4c1f56f commit 5c93aa5

File tree

2 files changed

+83
-4
lines changed

2 files changed

+83
-4
lines changed

Documentation/lkl.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,14 @@ are the list of those variable for your environment.
202202
```
203203
$ LKL_HIJACK_DEBUG=1 lkl-hijack.sh ip address show
204204
```
205+
* LKL_HIJACK_SINGLE_CPU
205206

207+
Pin LKL kernel threads on to a single host cpu. LKL_HIJACK_SINGLE_CPU=1 pins
208+
only LKL kernel threads while LKL_HIJACK_SINGLE_CPU=2 also pins polling
209+
threads.
210+
```
211+
$ LKL_HIJACK_SINGLE_CPU=1 lkl-hijack.sh ip address show
212+
```
206213
FAQ
207214
===
208215

tools/lkl/lib/hijack/init.c

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
#define __USE_GNU
3131
#include <dlfcn.h>
3232

33+
#define _GNU_SOURCE
34+
#include <sched.h>
35+
3336
/* Mount points are named after filesystem types so they should never
3437
* be longer than ~6 characters. */
3538
#define MAX_FSTYPE_LEN 50
@@ -177,6 +180,28 @@ void fixup_netdev_linux_fdnet_ops(void)
177180
lkl_netdev_linux_fdnet_ops.eventfd = dlsym(RTLD_NEXT, "eventfd");
178181
}
179182

183+
static void PinToCpus(const cpu_set_t* cpus)
184+
{
185+
if (sched_setaffinity(0, sizeof(cpu_set_t), cpus)) {
186+
perror("sched_setaffinity");
187+
}
188+
}
189+
190+
static void PinToFirstCpu(const cpu_set_t* cpus)
191+
{
192+
int j;
193+
cpu_set_t pinto;
194+
CPU_ZERO(&pinto);
195+
for (j = 0; j < CPU_SETSIZE; j++) {
196+
if (CPU_ISSET(j, cpus)) {
197+
lkl_printf("LKL: Pin To CPU %d\n", j);
198+
CPU_SET(j, &pinto);
199+
PinToCpus(&pinto);
200+
return;
201+
}
202+
}
203+
}
204+
180205
void __attribute__((constructor(102)))
181206
hijack_init(void)
182207
{
@@ -195,6 +220,51 @@ hijack_init(void)
195220
char *mount = getenv("LKL_HIJACK_MOUNT");
196221
struct lkl_netdev *nd = NULL;
197222
char *arp_entries = getenv("LKL_HIJACK_NET_ARP");
223+
/* single_cpu mode:
224+
* 0: Don't pin to single CPU (default).
225+
* 1: Pin only LKL kernel threads to single CPU.
226+
* 2: Pin all LKL threads to single CPU including all LKL kernel threads
227+
* and device polling threads. Avoid this mode if having busy polling
228+
* threads.
229+
*
230+
* mode 2 can achieve better TCP_RR but worse TCP_STREAM than mode 1.
231+
* You should choose the best for your application and virtio device
232+
* type.
233+
*/
234+
char *single_cpu= getenv("LKL_HIJACK_SINGLE_CPU");
235+
int single_cpu_mode = 0;
236+
cpu_set_t ori_cpu;
237+
238+
if (!debug)
239+
lkl_host_ops.print = NULL;
240+
else
241+
lkl_register_dbg_handler();
242+
243+
if (single_cpu) {
244+
single_cpu_mode = atoi(single_cpu);
245+
switch (single_cpu_mode) {
246+
case 0:
247+
case 1:
248+
case 2: break;
249+
default:
250+
fprintf(stderr, "single cpu mode must be 0~2.\n");
251+
single_cpu_mode = 0;
252+
break;
253+
}
254+
}
255+
256+
if (single_cpu_mode) {
257+
if (sched_getaffinity(0, sizeof(cpu_set_t), &ori_cpu)) {
258+
perror("sched_getaffinity");
259+
single_cpu_mode = 0;
260+
}
261+
}
262+
263+
/* Pin to a single cpu.
264+
* Any children thread created after it are pinned to the same CPU.
265+
*/
266+
if (single_cpu_mode == 2)
267+
PinToFirstCpu(&ori_cpu);
198268

199269
/* Must be run before lkl_netdev_tap_create */
200270
fixup_netdev_linux_fdnet_ops();
@@ -238,17 +308,19 @@ hijack_init(void)
238308
nd_id = ret;
239309
}
240310

241-
if (!debug)
242-
lkl_host_ops.print = NULL;
243-
else
244-
lkl_register_dbg_handler();
311+
if (single_cpu_mode == 1)
312+
PinToFirstCpu(&ori_cpu);
245313

246314
ret = lkl_start_kernel(&lkl_host_ops, 64 * 1024 * 1024, "");
247315
if (ret) {
248316
fprintf(stderr, "can't start kernel: %s\n", lkl_strerror(ret));
249317
return;
250318
}
251319

320+
/* restore cpu affinity */
321+
if (single_cpu_mode)
322+
PinToCpus(&ori_cpu);
323+
252324
/* fillup FDs up to LKL_FD_OFFSET */
253325
ret = lkl_sys_mknod("/dev_null", LKL_S_IFCHR | 0600, LKL_MKDEV(1, 3));
254326
dev_null = lkl_sys_open("/dev_null", LKL_O_RDONLY, 0);

0 commit comments

Comments
 (0)