Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/external/bsd linux: Use kmem directly for Linux kmalloc.



details:   https://anonhg.NetBSD.org/src/rev/6513aabbd8f2
branches:  trunk
changeset: 1028817:6513aabbd8f2
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Dec 19 12:07:55 2021 +0000

description:
linux: Use kmem directly for Linux kmalloc.

Take advantage of this to do LOCKDEBUG_MEM_CHECK at the point of
kfree_rcu rather than in the RCU GC thread.

diffstat:

 sys/external/bsd/common/include/linux/slab.h  |  65 ++++++++++++++++++++------
 sys/external/bsd/common/linux/linux_rcu.c     |   8 ++-
 sys/external/bsd/drm2/include/linux/mm.h      |  15 ++---
 sys/external/bsd/drm2/include/linux/vmalloc.h |  20 +++----
 4 files changed, 70 insertions(+), 38 deletions(-)

diffs (281 lines):

diff -r b98f00b6d1f2 -r 6513aabbd8f2 sys/external/bsd/common/include/linux/slab.h
--- a/sys/external/bsd/common/include/linux/slab.h      Sun Dec 19 12:07:47 2021 +0000
+++ b/sys/external/bsd/common/include/linux/slab.h      Sun Dec 19 12:07:55 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: slab.h,v 1.7 2021/12/19 12:00:48 riastradh Exp $       */
+/*     $NetBSD: slab.h,v 1.8 2021/12/19 12:07:55 riastradh Exp $       */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -33,7 +33,6 @@
 #define _LINUX_SLAB_H_
 
 #include <sys/kmem.h>
-#include <sys/malloc.h>
 
 #include <machine/limits.h>
 
@@ -44,10 +43,12 @@
 
 #define        ARCH_KMALLOC_MINALIGN   4 /* XXX ??? */
 
-/* XXX Should use kmem, but Linux kfree doesn't take the size.  */
+struct linux_malloc {
+       size_t  lm_size;
+} __aligned(ALIGNBYTES + 1);
 
 static inline int
-linux_gfp_to_malloc(gfp_t gfp)
+linux_gfp_to_kmem(gfp_t gfp)
 {
        int flags = 0;
 
@@ -62,7 +63,6 @@
        }
 
        if (ISSET(gfp, __GFP_ZERO)) {
-               flags |= M_ZERO;
                gfp &= ~__GFP_ZERO;
        }
 
@@ -75,31 +75,43 @@
            ((gfp & ~__GFP_WAIT) == (GFP_KERNEL & ~__GFP_WAIT)));
 
        if (ISSET(gfp, __GFP_WAIT)) {
-               flags |= M_WAITOK;
+               flags |= KM_SLEEP;
                gfp &= ~__GFP_WAIT;
        } else {
-               flags |= M_NOWAIT;
+               flags |= KM_NOSLEEP;
        }
 
        return flags;
 }
 
 /*
- * XXX vmalloc and kmalloc both use malloc(9).  If you change this, be
- * sure to update vmalloc in <linux/vmalloc.h> and kvfree in
- * <linux/mm.h>.
+ * XXX vmalloc and kmalloc both use this.  If you change that, be sure
+ * to update vmalloc in <linux/vmalloc.h> and kvfree in <linux/mm.h>.
  */
 
 static inline void *
 kmalloc(size_t size, gfp_t gfp)
 {
-       return malloc(size, M_TEMP, linux_gfp_to_malloc(gfp));
+       struct linux_malloc *lm;
+       int kmflags = linux_gfp_to_kmem(gfp);
+
+       KASSERTMSG(size < SIZE_MAX - sizeof(*lm), "size=%zu", size);
+
+       if (gfp & __GFP_ZERO)
+               lm = kmem_intr_zalloc(sizeof(*lm) + size, kmflags);
+       else
+               lm = kmem_intr_alloc(sizeof(*lm) + size, kmflags);
+       if (lm == NULL)
+               return NULL;
+
+       lm->lm_size = size;
+       return lm + 1;
 }
 
 static inline void *
 kzalloc(size_t size, gfp_t gfp)
 {
-       return malloc(size, M_TEMP, (linux_gfp_to_malloc(gfp) | M_ZERO));
+       return kmalloc(size, gfp | __GFP_ZERO);
 }
 
 static inline void *
@@ -107,7 +119,7 @@
 {
        if ((size != 0) && (n > (SIZE_MAX / size)))
                return NULL;
-       return malloc((n * size), M_TEMP, linux_gfp_to_malloc(gfp));
+       return kmalloc(n * size, gfp);
 }
 
 static inline void *
@@ -119,14 +131,35 @@
 static inline void *
 krealloc(void *ptr, size_t size, gfp_t gfp)
 {
-       return realloc(ptr, size, M_TEMP, linux_gfp_to_malloc(gfp));
+       struct linux_malloc *olm, *nlm;
+       int kmflags = linux_gfp_to_kmem(gfp);
+
+       if (gfp & __GFP_ZERO)
+               nlm = kmem_intr_zalloc(sizeof(*nlm) + size, kmflags);
+       else
+               nlm = kmem_intr_alloc(sizeof(*nlm) + size, kmflags);
+       if (nlm == NULL)
+               return NULL;
+
+       nlm->lm_size = size;
+       if (ptr) {
+               olm = (struct linux_malloc *)ptr - 1;
+               memcpy(nlm + 1, olm + 1, MIN(nlm->lm_size, olm->lm_size));
+               kmem_intr_free(olm, sizeof(*olm) + olm->lm_size);
+       }
+       return nlm + 1;
 }
 
 static inline void
 kfree(void *ptr)
 {
-       if (ptr != NULL)
-               free(ptr, M_TEMP);
+       struct linux_malloc *lm;
+
+       if (ptr == NULL)
+               return;
+
+       lm = (struct linux_malloc *)ptr - 1;
+       kmem_intr_free(lm, sizeof(*lm) + lm->lm_size);
 }
 
 #define        SLAB_HWCACHE_ALIGN      __BIT(0)
diff -r b98f00b6d1f2 -r 6513aabbd8f2 sys/external/bsd/common/linux/linux_rcu.c
--- a/sys/external/bsd/common/linux/linux_rcu.c Sun Dec 19 12:07:47 2021 +0000
+++ b/sys/external/bsd/common/linux/linux_rcu.c Sun Dec 19 12:07:55 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_rcu.c,v 1.4 2021/12/19 11:49:11 riastradh Exp $  */
+/*     $NetBSD: linux_rcu.c,v 1.5 2021/12/19 12:07:55 riastradh Exp $  */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,13 +30,15 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_rcu.c,v 1.4 2021/12/19 11:49:11 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_rcu.c,v 1.5 2021/12/19 12:07:55 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
+
 #include <sys/condvar.h>
 #include <sys/cpu.h>
 #include <sys/kthread.h>
+#include <sys/lockdebug.h>
 #include <sys/mutex.h>
 #include <sys/sdt.h>
 #include <sys/xcall.h>
@@ -191,6 +193,8 @@
 _kfree_rcu(struct rcu_head *head, void *obj)
 {
 
+       LOCKDEBUG_MEM_CHECK(obj, ((struct linux_malloc *)obj - 1)->lm_size);
+
        head->rcuh_u.obj = obj;
 
        mutex_enter(&gc.lock);
diff -r b98f00b6d1f2 -r 6513aabbd8f2 sys/external/bsd/drm2/include/linux/mm.h
--- a/sys/external/bsd/drm2/include/linux/mm.h  Sun Dec 19 12:07:47 2021 +0000
+++ b/sys/external/bsd/drm2/include/linux/mm.h  Sun Dec 19 12:07:55 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mm.h,v 1.22 2021/12/19 11:46:58 riastradh Exp $        */
+/*     $NetBSD: mm.h,v 1.23 2021/12/19 12:07:55 riastradh Exp $        */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -32,8 +32,6 @@
 #ifndef _LINUX_MM_H_
 #define _LINUX_MM_H_
 
-#include <sys/malloc.h>
-
 #include <uvm/uvm_extern.h>
 #include <uvm/uvm_object.h>
 
@@ -135,16 +133,15 @@
 }
 
 /*
- * XXX Requires that kmalloc in <linux/slab.h> and vmalloc in
- * <linux/vmalloc.h> both use malloc(9).  If you change either of
- * those, be sure to update this.
+ * XXX kvfree must additionally work on kmalloc (linux/slab.h) and
+ * vmalloc (linux/vmalloc.h).  If you change either of those, be sure
+ * to change this too.
  */
+
 static inline void
 kvfree(void *ptr)
 {
-
-       if (ptr != NULL)
-               free(ptr, M_TEMP);
+       kfree(ptr);
 }
 
 static inline void
diff -r b98f00b6d1f2 -r 6513aabbd8f2 sys/external/bsd/drm2/include/linux/vmalloc.h
--- a/sys/external/bsd/drm2/include/linux/vmalloc.h     Sun Dec 19 12:07:47 2021 +0000
+++ b/sys/external/bsd/drm2/include/linux/vmalloc.h     Sun Dec 19 12:07:55 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vmalloc.h,v 1.10 2021/12/19 10:51:24 riastradh Exp $   */
+/*     $NetBSD: vmalloc.h,v 1.11 2021/12/19 12:07:55 riastradh Exp $   */
 
 /*-
  * Copyright (c) 2013, 2018 The NetBSD Foundation, Inc.
@@ -32,21 +32,21 @@
 #ifndef _LINUX_VMALLOC_H_
 #define _LINUX_VMALLOC_H_
 
-#include <sys/malloc.h>
-
 #include <uvm/uvm_extern.h>
 
 #include <linux/mm.h>
 #include <linux/mm_types.h>
 #include <linux/overflow.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 
 struct notifier_block;
 
 /*
- * XXX vmalloc and kmalloc both use malloc(9).  If you change this, be
- * sure to update kmalloc in <linux/slab.h> and kvfree in <linux/mm.h>.
+ * XXX vmalloc and kvmalloc both use kmalloc.  If you change that, be
+ * sure to update this so kvfree in <linux/mm.h> still works on vmalloc
+ * addresses.
  */
 
 static inline bool
@@ -58,27 +58,25 @@
 static inline void *
 vmalloc(unsigned long size)
 {
-       return malloc(size, M_TEMP, M_WAITOK);
+       return kmalloc(size, GFP_KERNEL);
 }
 
 static inline void *
 vmalloc_user(unsigned long size)
 {
-       return malloc(size, M_TEMP, (M_WAITOK | M_ZERO));
+       return kzalloc(size, GFP_KERNEL);
 }
 
 static inline void *
 vzalloc(unsigned long size)
 {
-       return malloc(size, M_TEMP, (M_WAITOK | M_ZERO));
+       return kzalloc(size, GFP_KERNEL);
 }
 
 static inline void
 vfree(void *ptr)
 {
-       if (ptr == NULL)
-               return;
-       return free(ptr, M_TEMP);
+       return kfree(ptr);
 }
 
 #define        PAGE_KERNEL     UVM_PROT_RW



Home | Main Index | Thread Index | Old Index