git: 3b15beb30b3b - main - Implement malloc_domainset_aligned(9).

Alexander V. Chernikov melifaro at ipfw.ru
Mon Jan 18 20:45:50 UTC 2021


17.01.2021, 17:30, "Konstantin Belousov" <kib at freebsd.org>:
> The branch main has been updated by kib:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=3b15beb30b3b4ba17bae3d1d43c8c04ff862bb57
>
> commit 3b15beb30b3b4ba17bae3d1d43c8c04ff862bb57
> Author: Konstantin Belousov <kib at FreeBSD.org>
> AuthorDate: 2021-01-14 03:59:34 +0000
> Commit: Konstantin Belousov <kib at FreeBSD.org>
> CommitDate: 2021-01-17 17:29:05 +0000
>
>     Implement malloc_domainset_aligned(9).
Hi Kostik,

This change makes my vm panic in usb code. No dump, as dumpdev not mounted yet.

Note: the below lines have been OCR'ed, so there may be some errors.

Root mount waiting for: CAM usbus0 usbus1
panic: malloc_domainset_aligned: result not aligned 0xfffff8000551ca80 size 0x180 align 0x100
cpuid = 1
time = 2
KDB: stack backtrace:
db_trace_self_urapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe004d6345c0
vpanic() at vpanic+0x181 /frame 0xfffffe004d634610
panic() at panic+0x43/frame 0xfffffe004d634670
malloc_domainset_aligned() at malloc_domainset_aligned+0x8e/frame 0xfffffe004d6346a0 bounce_bus_dmamem_alloc() at bounce_bus_dmamem_alloc+0xde/frame 0xfffffe004d6346d0
usb_pc_alloc_mem() at usb_pc_alloc_mem+0x7c/frame 0xfffffe004d634730
usbd_transfer_setup_sub_malloc() at usbd_transfer_setup_sub_malloc+0x2fc/frame 0xfffffe004d6347c0
uhci_xfer_setup() at uhci_xfer_setup+0x1c9/frame 0xfffffe004d634840
usbd_transfer_setup() at usbd_transfer_setup+0x64a/frame 0xfffffe004d634910
usbd_ctr l_transfer_setup() at usbd_ctrl_transfer_setup+0xad/frame 0xfffffe004d634960
usbd_do_reguest_flags() at usbd_do_reguest_flags+0x220/frame 0xfffffe004d6349f0
usbd_reg_set_addressO at usbd_reg_set_address+0x9d/frame 0xfffffe004d634a30
usb_alloc_device() at usb_alloc_device+0x50e/frame 0xfffffe004d634ae0
uhub_explore() at uhub_explore+0x584/frame 0xfffffe004d634b60
usb_bus_explore() at usb_bus_explore+0x117/frame 0xfffffe004d634b80
usb_process() at usb_process+0xf3/frame 0xfffffe004d634bb0
fork_exit() at fork_exit+0x80/frame 0xfffffe004d634bf0
fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe004d634bf0

After converting KASSERT to printf:

malloc_domainset_aligned: result not aligned 0xfffff80005309a80 size 0x180 align 0x100
bus_dmamem_alloc failed to align memory properly.
malloc_domainset_aligned: result not aligned 0xfffff80005309a80 size 0x180 align 0x100
bus_dmamem_alloc failed to align memory properly.
ugen0.2: <VMware VMware Virtual USB Mouse> at usbus0
Root mount waiting for: CAM usbus0 usbus1
malloc_domainset_aligned: result not aligned 0xfffff80005309780 size 0x180 align 0x100
bus_dmamem_alloc failed to align memory properly.
malloc_domainset_aligned: result not aligned 0xfffff80005309780 size 0x180 align 0x100
bus_dmamem_alloc failed to align memory properly.
ugen0.3: <VMware, Inc. VMware Virtual USB Hub> at usbus0
uhub2 on uhub0
uhub2: <VMware, Inc.> on usbus0
malloc_domainset_aligned: result not aligned 0xfffff80005309480 size 0x180 align 0x100
bus_dmamem_alloc failed to align memory properly.
malloc_domainset_aligned: result not aligned 0xfffff80005309180 size 0x180 align 0x100
bus_dmamem_alloc failed to align memory properly.


>
>     Change the power-of-two malloc zones to require alignment equal to the
>     size [*]. Current uma allocator already provides such alignment, so in
>     fact this change does not change anything except providing future-proof
>     setup.
>
>     Suggested by: markj [*]
>     Reviewed by: andrew, jah, markj
>     Tested by: pho
>     MFC after: 1 week
>     Sponsored by: The FreeBSD Foundation
>     Differential Revision: https://reviews.freebsd.org/D28147
> ---
>  sys/kern/kern_malloc.c | 28 +++++++++++++++++++++++++++-
>  sys/sys/malloc.h | 3 +++
>  2 files changed, 30 insertions(+), 1 deletion(-)
>
> diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
> index f79352f2fbfd..232472708b9b 100644
> --- a/sys/kern/kern_malloc.c
> +++ b/sys/kern/kern_malloc.c
> @@ -763,6 +763,28 @@ malloc_domainset_exec(size_t size, struct malloc_type *mtp, struct domainset *ds
>          return (malloc_large(&size, mtp, ds, flags DEBUG_REDZONE_ARG));
>  }
>
> +void *
> +malloc_domainset_aligned(size_t size, size_t align,
> + struct malloc_type *mtp, struct domainset *ds, int flags)
> +{
> + void *res;
> +
> + KASSERT(align != 0 && powerof2(align),
> + ("malloc_domainset_aligned: wrong align %#zx size %#zx",
> + align, size));
> + KASSERT(align <= kmemzones[nitems(kmemzones) - 2].kz_size,
> + ("malloc_domainset_aligned: align %#zx (size %#zx) too large",
> + align, size));
> +
> + if (size < align)
> + size = align;
> + res = malloc_domainset(size, mtp, ds, flags);
> + KASSERT(res == NULL || ((uintptr_t)res & (align - 1)) == 0,
> + ("malloc_domainset_aligned: result not aligned %p size %#zx "
> + "align %#zx", res, size, align));
> + return (res);
> +}
> +
>  void *
>  mallocarray(size_t nmemb, size_t size, struct malloc_type *type, int flags)
>  {
> @@ -1146,8 +1168,12 @@ mallocinit(void *dummy)
>          for (i = 0, indx = 0; kmemzones[indx].kz_size != 0; indx++) {
>                  int size = kmemzones[indx].kz_size;
>                  const char *name = kmemzones[indx].kz_name;
> + size_t align;
>                  int subzone;
>
> + align = UMA_ALIGN_PTR;
> + if (powerof2(size) && size > sizeof(void *))
> + align = size - 1;
>                  for (subzone = 0; subzone < numzones; subzone++) {
>                          kmemzones[indx].kz_zone[subzone] =
>                              uma_zcreate(name, size,
> @@ -1156,7 +1182,7 @@ mallocinit(void *dummy)
>  #else
>                              NULL, NULL, NULL, NULL,
>  #endif
> - UMA_ALIGN_PTR, UMA_ZONE_MALLOC);
> + align, UMA_ZONE_MALLOC);
>                  }
>                  for (;i <= size; i+= KMEM_ZBASE)
>                          kmemsize[i >> KMEM_ZSHIFT] = indx;
> diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h
> index bf87e3168e01..a11dd767efc5 100644
> --- a/sys/sys/malloc.h
> +++ b/sys/sys/malloc.h
> @@ -261,6 +261,9 @@ 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)
>              __result_use_check __alloc_size(2);
> +void *malloc_domainset_aligned(size_t size, size_t align,
> + struct malloc_type *mtp, struct domainset *ds, int flags)
> + __malloc_like __result_use_check __alloc_size(1);
>
>  struct malloc_type *malloc_desc2type(const char *desc);


More information about the dev-commits-src-all mailing list