Skip to content

Commit 8302b9b

Browse files
qmonnetborkmann
authored andcommitted
tools: bpftool: adjust rlimit RLIMIT_MEMLOCK when loading programs, maps
The limit for memory locked in the kernel by a process is usually set to 64 kbytes by default. This can be an issue when creating large BPF maps and/or loading many programs. A workaround is to raise this limit for the current process before trying to create a new BPF map. Changing the hard limit requires the CAP_SYS_RESOURCE and can usually only be done by root user (for non-root users, a call to setrlimit fails (and sets errno) and the program simply goes on with its rlimit unchanged). There is no API to get the current amount of memory locked for a user, therefore we cannot raise the limit only when required. One solution, used by bcc, is to try to create the map, and on getting a EPERM error, raising the limit to infinity before giving another try. Another approach, used in iproute2, is to raise the limit in all cases, before trying to create the map. Here we do the same as in iproute2: the rlimit is raised to infinity before trying to load programs or to create maps with bpftool. Signed-off-by: Quentin Monnet <[email protected]> Reviewed-by: Jakub Kicinski <[email protected]> Acked-by: Martin KaFai Lau <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent f96afa7 commit 8302b9b

File tree

4 files changed

+14
-0
lines changed

4 files changed

+14
-0
lines changed

tools/bpf/bpftool/common.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include <linux/magic.h>
4747
#include <net/if.h>
4848
#include <sys/mount.h>
49+
#include <sys/resource.h>
4950
#include <sys/stat.h>
5051
#include <sys/types.h>
5152
#include <sys/vfs.h>
@@ -99,6 +100,13 @@ static bool is_bpffs(char *path)
99100
return (unsigned long)st_fs.f_type == BPF_FS_MAGIC;
100101
}
101102

103+
void set_max_rlimit(void)
104+
{
105+
struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
106+
107+
setrlimit(RLIMIT_MEMLOCK, &rinf);
108+
}
109+
102110
static int mnt_bpffs(const char *target, char *buff, size_t bufflen)
103111
{
104112
bool bind_done = false;

tools/bpf/bpftool/main.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ bool is_prefix(const char *pfx, const char *str);
100100
void fprint_hex(FILE *f, void *arg, unsigned int n, const char *sep);
101101
void usage(void) __noreturn;
102102

103+
void set_max_rlimit(void);
104+
103105
struct pinned_obj_table {
104106
DECLARE_HASHTABLE(table, 16);
105107
};

tools/bpf/bpftool/map.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,8 @@ static int do_create(int argc, char **argv)
11401140
return -1;
11411141
}
11421142

1143+
set_max_rlimit();
1144+
11431145
fd = bpf_create_map_xattr(&attr);
11441146
if (fd < 0) {
11451147
p_err("map create failed: %s", strerror(errno));

tools/bpf/bpftool/prog.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,8 @@ static int do_load(int argc, char **argv)
995995
goto err_close_obj;
996996
}
997997

998+
set_max_rlimit();
999+
9981000
err = bpf_object__load(obj);
9991001
if (err) {
10001002
p_err("failed to load object file");

0 commit comments

Comments
 (0)