On Wed, Jan 31, 2018 at 8:53 AM, Björn Töpel <[email protected]> wrote:
> From: Björn Töpel <[email protected]>
>
> The XDP_MEM_REG socket option allows a process to register a window of
> user space memory to the kernel. This memory will later be used as
> frame data buffer.
>
> Signed-off-by: Björn Töpel <[email protected]>
> ---
> +static struct xsk_umem *xsk_mem_reg(u64 addr, u64 size, u32 frame_size,
> + u32 data_headroom)
> +{
> + unsigned long lock_limit, locked, npages;
> + int ret = 0;
> + struct xsk_umem *umem;
> +
> + if (!can_do_mlock())
> + return ERR_PTR(-EPERM);
> +
> + umem = xsk_umem_create(addr, size, frame_size, data_headroom);
> + if (IS_ERR(umem))
> + return umem;
> +
> + npages = PAGE_ALIGN(umem->nframes * umem->frame_size) >> PAGE_SHIFT;
> +
> + down_write(¤t->mm->mmap_sem);
> +
> + locked = npages + current->mm->pinned_vm;
> + lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
> +
> + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) {
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + if (npages == 0 || npages > UINT_MAX) {
> + ret = -EINVAL;
> + goto out;
> + }
> + umem->npgs = npages;
> +
> + ret = xsk_umem_pin_pages(umem);
> +
> +out:
> + if (ret < 0) {
> + put_pid(umem->pid);
> + kfree(umem);
> + } else {
> + current->mm->pinned_vm = locked;
> + }
> +
> + up_write(¤t->mm->mmap_sem);
This limits per process. You may want to limit per user. See also
mm_account_pinned_pages.