Re: [PATCH RFC 3/3] mm/vmalloc: remove vwrite()

From: Michal Hocko
Date: Mon Mar 22 2021 - 09:37:02 EST


On Fri 19-03-21 15:34:52, David Hildenbrand wrote:
> The last user (/dev/kmem) is gone. Let's drop it.
>
> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
> Cc: Hillf Danton <hdanton@xxxxxxxx>
> Cc: Michal Hocko <mhocko@xxxxxxxx>
> Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx>
> Cc: Oleksiy Avramchenko <oleksiy.avramchenko@xxxxxxxxxxxxxx>
> Cc: Steven Rostedt <rostedt@xxxxxxxxxxx>
> Cc: Minchan Kim <minchan@xxxxxxxxxx>
> Cc: huang ying <huang.ying.caritas@xxxxxxxxx>
> Signed-off-by: David Hildenbrand <david@xxxxxxxxxx>

Acked-by: Michal Hocko <mhocko@xxxxxxxx>

> ---
> include/linux/vmalloc.h | 1 -
> mm/vmalloc.c | 111 ----------------------------------------
> 2 files changed, 112 deletions(-)
>
> diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
> index 390af680e916..9c1b17c7dd95 100644
> --- a/include/linux/vmalloc.h
> +++ b/include/linux/vmalloc.h
> @@ -200,7 +200,6 @@ static inline void set_vm_flush_reset_perms(void *addr)
>
> /* for /proc/kcore */
> extern long vread(char *buf, char *addr, unsigned long count);
> -extern long vwrite(char *buf, char *addr, unsigned long count);
>
> /*
> * Internals. Dont't use..
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index ccb405b82581..07a39881f9d6 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -2820,43 +2820,6 @@ static int aligned_vread(char *buf, char *addr, unsigned long count)
> return copied;
> }
>
> -static int aligned_vwrite(char *buf, char *addr, unsigned long count)
> -{
> - struct page *p;
> - int copied = 0;
> -
> - while (count) {
> - unsigned long offset, length;
> -
> - offset = offset_in_page(addr);
> - length = PAGE_SIZE - offset;
> - if (length > count)
> - length = count;
> - p = vmalloc_to_page(addr);
> - /*
> - * To do safe access to this _mapped_ area, we need
> - * lock. But adding lock here means that we need to add
> - * overhead of vmalloc()/vfree() calles for this _debug_
> - * interface, rarely used. Instead of that, we'll use
> - * kmap() and get small overhead in this access function.
> - */
> - if (p) {
> - /*
> - * we can expect USER0 is not used (see vread/vwrite's
> - * function description)
> - */
> - void *map = kmap_atomic(p);
> - memcpy(map + offset, buf, length);
> - kunmap_atomic(map);
> - }
> - addr += length;
> - buf += length;
> - copied += length;
> - count -= length;
> - }
> - return copied;
> -}
> -
> /**
> * vread() - read vmalloc area in a safe way.
> * @buf: buffer for reading data
> @@ -2936,80 +2899,6 @@ long vread(char *buf, char *addr, unsigned long count)
> return buflen;
> }
>
> -/**
> - * vwrite() - write vmalloc area in a safe way.
> - * @buf: buffer for source data
> - * @addr: vm address.
> - * @count: number of bytes to be read.
> - *
> - * This function checks that addr is a valid vmalloc'ed area, and
> - * copy data from a buffer to the given addr. If specified range of
> - * [addr...addr+count) includes some valid address, data is copied from
> - * proper area of @buf. If there are memory holes, no copy to hole.
> - * IOREMAP area is treated as memory hole and no copy is done.
> - *
> - * If [addr...addr+count) doesn't includes any intersects with alive
> - * vm_struct area, returns 0. @buf should be kernel's buffer.
> - *
> - * Note: In usual ops, vwrite() is never necessary because the caller
> - * should know vmalloc() area is valid and can use memcpy().
> - * This is for routines which have to access vmalloc area without
> - * any information, as /dev/kmem.
> - *
> - * Return: number of bytes for which addr and buf should be
> - * increased (same number as @count) or %0 if [addr...addr+count)
> - * doesn't include any intersection with valid vmalloc area
> - */
> -long vwrite(char *buf, char *addr, unsigned long count)
> -{
> - struct vmap_area *va;
> - struct vm_struct *vm;
> - char *vaddr;
> - unsigned long n, buflen;
> - int copied = 0;
> -
> - /* Don't allow overflow */
> - if ((unsigned long) addr + count < count)
> - count = -(unsigned long) addr;
> - buflen = count;
> -
> - spin_lock(&vmap_area_lock);
> - list_for_each_entry(va, &vmap_area_list, list) {
> - if (!count)
> - break;
> -
> - if (!va->vm)
> - continue;
> -
> - vm = va->vm;
> - vaddr = (char *) vm->addr;
> - if (addr >= vaddr + get_vm_area_size(vm))
> - continue;
> - while (addr < vaddr) {
> - if (count == 0)
> - goto finished;
> - buf++;
> - addr++;
> - count--;
> - }
> - n = vaddr + get_vm_area_size(vm) - addr;
> - if (n > count)
> - n = count;
> - if (!(vm->flags & VM_IOREMAP)) {
> - aligned_vwrite(buf, addr, n);
> - copied++;
> - }
> - buf += n;
> - addr += n;
> - count -= n;
> - }
> -finished:
> - spin_unlock(&vmap_area_lock);
> - if (!copied)
> - return 0;
> - return buflen;
> -}
> -
> /**
> * remap_vmalloc_range_partial - map vmalloc pages to userspace
> * @vma: vma to cover
> --
> 2.29.2

--
Michal Hocko
SUSE Labs