insumity
insumity

Reputation: 5459

set_mempolicy from a different process

For NUMA machines, Linux provides the set_mempolicy system call that allows a process to define its preferred NUMA node for memory allocations.

Is there some similar function that allows to change the memory policy of another running process? So something like this set_mempolicy(pid, ...) where pid corresponds to a different running process?

Note, that the other process (the one I want to change its memory policy) is already running and I have no control over it. So a solution like this:

set_mempolicy(...);
fork(); // now new process has the same memory policy

is not what I'm looking for.

Upvotes: 2

Views: 1507

Answers (2)

Useless
Useless

Reputation: 67743

  1. create a cpuset with mems containing the desired node(s), and memory_migrate containing 1
  2. write the process' PID into the cpuset's tasks file

New allocations by the process will be fulfilled according to the cpuset's mems config, and existing pages will be migrated when the task is added to the set.

NB. This feels like a serverfault Q/A really, but your can write your cpuset management in C if it makes you feel better.

Upvotes: 2

codegrep_admin
codegrep_admin

Reputation: 529

There are few ways to implement given that I assume that you are unable to change the program.

  1. Implement what NUMA policy would achieve by in userspace. It is possible to move pages for a process between different NUMA nodes. See migratepages. I'd imagine you'd have to run this once in a while.

  2. Otherwise, you can attach via gdb and set the policy. Note, I am not 100% certain if this will affect pages already allocated. You might have to run migratepages before this step.

Create a function that sets your preferred numa policy:

inject.c

#include "inject.h"

void inject(){
   printf("Changing memory policy\n");
   unsigned long nodemask = 1L << 1;
   set_mempolicy(MPOL_PREFERRED, &nodemask, 3);
}

inject.h

#include <stdio.h>
#include <numaif.h>
extern void inject();

libinject.so

gcc -c -Wall -Werror -lnuma -fPIC inject.c
gcc -shared -o libinject.so inject.o -lnuma

** Attach to pid and call the function you have defined **

gdb -p pid
(gdb) call __libc_dlopen_mode("/path_to/libinject.so", 0x0002)
(gdb) call  inject()

I have verified that I am able to change numa policy via /proc/pid/numa_maps ( changed from default to prefer:1 ) but I am not too familiar with numa to say that change is effective.

Please note that this is invasive process and hopefully there is a simpler alternative.

Upvotes: 0

Related Questions