Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 6 Sep 2020 17:40:35 +0000 (UTC)
From:      Vladimir Kondratyev <wulf@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r365383 - in stable/12: share/man/man9 sys/compat/linuxkpi/common/include/linux sys/kern sys/sys sys/vm
Message-ID:  <202009061740.086HeZDQ061127@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: wulf
Date: Sun Sep  6 17:40:35 2020
New Revision: 365383
URL: https://svnweb.freebsd.org/changeset/base/365383

Log:
  MFC r364964: LinuxKPI: Implement ksize() function.
  
  In Linux, ksize() gets the actual amount of memory allocated for a given
  object. This commit adds malloc_usable_size() to FreeBSD KPI which does
  the same. It also maps LinuxKPI ksize() to newly created function.
  
  ksize() function is used by drm-kmod.
  
  Reviewed by:	hselasky, kib
  Differential Revision:	https://reviews.freebsd.org/D26215

Modified:
  stable/12/share/man/man9/malloc.9
  stable/12/sys/compat/linuxkpi/common/include/linux/slab.h
  stable/12/sys/kern/kern_malloc.c
  stable/12/sys/sys/malloc.h
  stable/12/sys/vm/memguard.c
  stable/12/sys/vm/memguard.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/share/man/man9/malloc.9
==============================================================================
--- stable/12/share/man/man9/malloc.9	Sun Sep  6 15:44:09 2020	(r365382)
+++ stable/12/share/man/man9/malloc.9	Sun Sep  6 17:40:35 2020	(r365383)
@@ -29,7 +29,7 @@
 .\" $NetBSD: malloc.9,v 1.3 1996/11/11 00:05:11 lukem Exp $
 .\" $FreeBSD$
 .\"
-.Dd October 30, 2018
+.Dd August 28, 2020
 .Dt MALLOC 9
 .Os
 .Sh NAME
@@ -53,6 +53,8 @@
 .Fn realloc "void *addr" "size_t size" "struct malloc_type *type" "int flags"
 .Ft void *
 .Fn reallocf "void *addr" "size_t size" "struct malloc_type *type" "int flags"
+.Ft size_t
+.Fn malloc_usable_size "const void *addr"
 .Fn MALLOC_DECLARE type
 .In sys/param.h
 .In sys/malloc.h
@@ -138,6 +140,13 @@ function is identical to
 .Fn realloc
 except that it
 will free the passed pointer when the requested memory cannot be allocated.
+.Pp
+The
+.Fn malloc_usable_size
+function returns the usable size of the allocation pointed to by
+.Fa addr .
+The return value may be larger than the size that was requested during
+allocation.
 .Pp
 Unlike its standard C library counterpart
 .Pq Xr malloc 3 ,

Modified: stable/12/sys/compat/linuxkpi/common/include/linux/slab.h
==============================================================================
--- stable/12/sys/compat/linuxkpi/common/include/linux/slab.h	Sun Sep  6 15:44:09 2020	(r365382)
+++ stable/12/sys/compat/linuxkpi/common/include/linux/slab.h	Sun Sep  6 17:40:35 2020	(r365383)
@@ -154,6 +154,12 @@ kfree(const void *ptr)
 	free(__DECONST(void *, ptr), M_KMALLOC);
 }
 
+static inline size_t
+ksize(const void *ptr)
+{
+	return (malloc_usable_size(ptr));
+}
+
 extern struct linux_kmem_cache *linux_kmem_cache_create(const char *name,
     size_t size, size_t align, unsigned flags, linux_kmem_ctor_t *ctor);
 

Modified: stable/12/sys/kern/kern_malloc.c
==============================================================================
--- stable/12/sys/kern/kern_malloc.c	Sun Sep  6 15:44:09 2020	(r365382)
+++ stable/12/sys/kern/kern_malloc.c	Sun Sep  6 17:40:35 2020	(r365383)
@@ -867,6 +867,41 @@ reallocf(void *addr, size_t size, struct malloc_type *
 	return (mem);
 }
 
+/*
+ *	malloc_usable_size: returns the usable size of the allocation.
+ */
+size_t
+malloc_usable_size(const void *addr)
+{
+#ifndef DEBUG_REDZONE
+	uma_slab_t slab;
+#endif
+	u_long size;
+
+	if (addr == NULL)
+		return (0);
+
+#ifdef DEBUG_MEMGUARD
+	if (is_memguard_addr(__DECONST(void *, addr)))
+		return (memguard_get_req_size(addr));
+#endif
+
+#ifdef DEBUG_REDZONE
+	size = redzone_get_size(__DECONST(void *, addr));
+#else
+	slab = vtoslab((vm_offset_t)addr & (~UMA_SLAB_MASK));
+	if (slab == NULL)
+		panic("malloc_usable_size: address %p(%p) is not allocated.\n",
+		    addr, (void *)((u_long)addr & (~UMA_SLAB_MASK)));
+
+	if (!(slab->us_flags & UMA_SLAB_MALLOC))
+		size = slab->us_keg->uk_size;
+	else
+		size = slab->us_size;
+#endif
+	return (size);
+}
+
 #ifndef __sparc64__
 CTASSERT(VM_KMEM_SIZE_SCALE >= 1);
 #endif

Modified: stable/12/sys/sys/malloc.h
==============================================================================
--- stable/12/sys/sys/malloc.h	Sun Sep  6 15:44:09 2020	(r365382)
+++ stable/12/sys/sys/malloc.h	Sun Sep  6 17:40:35 2020	(r365383)
@@ -244,6 +244,7 @@ void	malloc_type_allocated(struct malloc_type *type, u
 void	malloc_type_freed(struct malloc_type *type, unsigned long size);
 void	malloc_type_list(malloc_type_list_func_t *, void *);
 void	malloc_uninit(void *);
+size_t	malloc_usable_size(const void *);
 void	*realloc(void *addr, size_t size, struct malloc_type *type, int flags)
 	    __result_use_check __alloc_size(2);
 void	*reallocf(void *addr, size_t size, struct malloc_type *type, int flags)

Modified: stable/12/sys/vm/memguard.c
==============================================================================
--- stable/12/sys/vm/memguard.c	Sun Sep  6 15:44:09 2020	(r365382)
+++ stable/12/sys/vm/memguard.c	Sun Sep  6 17:40:35 2020	(r365383)
@@ -503,3 +503,9 @@ memguard_cmp_zone(uma_zone_t zone)
 	 */
 	return (strcmp(zone->uz_name, vm_memguard_desc) == 0);
 }
+
+unsigned long
+memguard_get_req_size(const void *addr)
+{
+	return (*v2sizep(trunc_page((uintptr_t)addr)));
+}

Modified: stable/12/sys/vm/memguard.h
==============================================================================
--- stable/12/sys/vm/memguard.h	Sun Sep  6 15:44:09 2020	(r365382)
+++ stable/12/sys/vm/memguard.h	Sun Sep  6 17:40:35 2020	(r365383)
@@ -43,6 +43,7 @@ void	memguard_init(struct vmem *);
 void 	*memguard_alloc(unsigned long, int);
 void	*memguard_realloc(void *, unsigned long, struct malloc_type *, int);
 void	memguard_free(void *);
+unsigned long	memguard_get_req_size(const void *);
 int	memguard_cmp_mtp(struct malloc_type *, unsigned long);
 int	memguard_cmp_zone(uma_zone_t);
 int	is_memguard_addr(void *);
@@ -52,6 +53,7 @@ int	is_memguard_addr(void *);
 #define	memguard_alloc(size, flags)	NULL
 #define	memguard_realloc(a, s, mtp, f)	NULL
 #define	memguard_free(addr)		do { } while (0)
+#define	memguard_get_req_size(addr)	0
 #define	memguard_cmp_mtp(mtp, size)	0
 #define	memguard_cmp_zone(zone)		0
 #define	is_memguard_addr(addr)		0



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202009061740.086HeZDQ061127>