Message ID | e225c943767e175b2431a8f23699b7dad5e2758b.1481935106.git.daniel@iogearbox.net |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
Hi Daniel, [auto build test ERROR on net/master] url: https://github.com/0day-ci/linux/commits/Daniel-Borkmann/bpf-dynamically-allocate-digest-scratch-buffer/20161217-090046 config: sparc-defconfig (attached as .config) compiler: sparc-linux-gcc (GCC) 6.2.0 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=sparc All errors (new ones prefixed by >>): kernel/bpf/core.c: In function '__bpf_prog_charge': >> kernel/bpf/core.c:80:50: error: 'struct user_struct' has no member named 'locked_vm'; did you mean 'locked_shm'? user_bufs = atomic_long_add_return(pages, &user->locked_vm); ^~ kernel/bpf/core.c:82:32: error: 'struct user_struct' has no member named 'locked_vm'; did you mean 'locked_shm'? atomic_long_sub(pages, &user->locked_vm); ^~ kernel/bpf/core.c: In function '__bpf_prog_uncharge': kernel/bpf/core.c:93:31: error: 'struct user_struct' has no member named 'locked_vm'; did you mean 'locked_shm'? atomic_long_sub(pages, &user->locked_vm); ^~ vim +80 kernel/bpf/core.c 74 static int __bpf_prog_charge(struct user_struct *user, u32 pages) 75 { 76 unsigned long memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; 77 unsigned long user_bufs; 78 79 if (user) { > 80 user_bufs = atomic_long_add_return(pages, &user->locked_vm); 81 if (user_bufs > memlock_limit) { 82 atomic_long_sub(pages, &user->locked_vm); 83 return -EPERM; --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Daniel, [auto build test ERROR on net/master] url: https://github.com/0day-ci/linux/commits/Daniel-Borkmann/bpf-dynamically-allocate-digest-scratch-buffer/20161217-090046 config: openrisc-or1ksim_defconfig (attached as .config) compiler: or32-linux-gcc (GCC) 4.5.1-or32-1.0rc1 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=openrisc All errors (new ones prefixed by >>): kernel/bpf/core.c: In function '__bpf_prog_charge': >> kernel/bpf/core.c:80:50: error: 'struct user_struct' has no member named 'locked_vm' kernel/bpf/core.c:82:32: error: 'struct user_struct' has no member named 'locked_vm' kernel/bpf/core.c: In function '__bpf_prog_uncharge': kernel/bpf/core.c:93:31: error: 'struct user_struct' has no member named 'locked_vm' vim +80 kernel/bpf/core.c 74 static int __bpf_prog_charge(struct user_struct *user, u32 pages) 75 { 76 unsigned long memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; 77 unsigned long user_bufs; 78 79 if (user) { > 80 user_bufs = atomic_long_add_return(pages, &user->locked_vm); 81 if (user_bufs > memlock_limit) { 82 atomic_long_sub(pages, &user->locked_vm); 83 return -EPERM; --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
On 12/17/2016 03:52 AM, kbuild test robot wrote: > Hi Daniel, > > [auto build test ERROR on net/master] > > url: https://github.com/0day-ci/linux/commits/Daniel-Borkmann/bpf-dynamically-allocate-digest-scratch-buffer/20161217-090046 > config: sparc-defconfig (attached as .config) > compiler: sparc-linux-gcc (GCC) 6.2.0 > reproduce: > wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # save the attached .config to linux build tree > make.cross ARCH=sparc > > All errors (new ones prefixed by >>): > > kernel/bpf/core.c: In function '__bpf_prog_charge': >>> kernel/bpf/core.c:80:50: error: 'struct user_struct' has no member named 'locked_vm'; did you mean 'locked_shm'? > user_bufs = atomic_long_add_return(pages, &user->locked_vm); > ^~ > kernel/bpf/core.c:82:32: error: 'struct user_struct' has no member named 'locked_vm'; did you mean 'locked_shm'? > atomic_long_sub(pages, &user->locked_vm); > ^~ > kernel/bpf/core.c: In function '__bpf_prog_uncharge': > kernel/bpf/core.c:93:31: error: 'struct user_struct' has no member named 'locked_vm'; did you mean 'locked_shm'? > atomic_long_sub(pages, &user->locked_vm); Argh, right, I'll send v2 later today.
diff --git a/include/linux/filter.h b/include/linux/filter.h index a0934e6..496a8c0 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -577,6 +577,9 @@ struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size, gfp_t gfp_extra_flags); void __bpf_prog_free(struct bpf_prog *fp); +int bpf_prog_charge_memlock(struct bpf_prog *prog); +void bpf_prog_uncharge_memlock(struct bpf_prog *prog); + static inline void bpf_prog_unlock_free(struct bpf_prog *fp) { bpf_prog_unlock_ro(fp); diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 75c08b8..1f9a146 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -71,6 +71,51 @@ void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, uns return NULL; } +static int __bpf_prog_charge(struct user_struct *user, u32 pages) +{ + unsigned long memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; + unsigned long user_bufs; + + if (user) { + user_bufs = atomic_long_add_return(pages, &user->locked_vm); + if (user_bufs > memlock_limit) { + atomic_long_sub(pages, &user->locked_vm); + return -EPERM; + } + } + + return 0; +} + +static void __bpf_prog_uncharge(struct user_struct *user, u32 pages) +{ + if (user) + atomic_long_sub(pages, &user->locked_vm); +} + +int bpf_prog_charge_memlock(struct bpf_prog *prog) +{ + struct user_struct *user = get_current_user(); + int ret; + + ret = __bpf_prog_charge(user, prog->pages); + if (ret) { + free_uid(user); + return ret; + } + + prog->aux->user = user; + return 0; +} + +void bpf_prog_uncharge_memlock(struct bpf_prog *prog) +{ + struct user_struct *user = prog->aux->user; + + __bpf_prog_uncharge(user, prog->pages); + free_uid(user); +} + struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags) { gfp_t gfp_flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO | @@ -105,19 +150,29 @@ struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size, gfp_t gfp_flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO | gfp_extra_flags; struct bpf_prog *fp; + u32 pages, delta; + int ret; BUG_ON(fp_old == NULL); size = round_up(size, PAGE_SIZE); - if (size <= fp_old->pages * PAGE_SIZE) + pages = size / PAGE_SIZE; + if (pages <= fp_old->pages) return fp_old; + delta = pages - fp_old->pages; + ret = __bpf_prog_charge(fp_old->aux->user, delta); + if (ret) + return NULL; + fp = __vmalloc(size, gfp_flags, PAGE_KERNEL); - if (fp != NULL) { + if (fp == NULL) { + __bpf_prog_uncharge(fp_old->aux->user, delta); + } else { kmemcheck_annotate_bitfield(fp, meta); memcpy(fp, fp_old, fp_old->pages * PAGE_SIZE); - fp->pages = size / PAGE_SIZE; + fp->pages = pages; fp->aux->prog = fp; /* We keep fp->aux from fp_old around in the new diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 35d674c..016382b 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -615,31 +615,6 @@ static void free_used_maps(struct bpf_prog_aux *aux) kfree(aux->used_maps); } -static int bpf_prog_charge_memlock(struct bpf_prog *prog) -{ - struct user_struct *user = get_current_user(); - unsigned long memlock_limit; - - memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; - - atomic_long_add(prog->pages, &user->locked_vm); - if (atomic_long_read(&user->locked_vm) > memlock_limit) { - atomic_long_sub(prog->pages, &user->locked_vm); - free_uid(user); - return -EPERM; - } - prog->aux->user = user; - return 0; -} - -static void bpf_prog_uncharge_memlock(struct bpf_prog *prog) -{ - struct user_struct *user = prog->aux->user; - - atomic_long_sub(prog->pages, &user->locked_vm); - free_uid(user); -} - static void __bpf_prog_put_rcu(struct rcu_head *rcu) { struct bpf_prog_aux *aux = container_of(rcu, struct bpf_prog_aux, rcu);