Commit 4cd687b8 authored by HardenedBSD Sync Service's avatar HardenedBSD Sync Service
Browse files

Merge branch 'freebsd/12-stable/main' into hardened/12-stable/master

* freebsd/12-stable/main:
  pf: pool/kpool conversion code
  MFC dfb33cb0: Allocating the LinuxKPI current structure from a software interrupt thread must be done using the M_NOWAIT flag after 1ae20f7c .
  MFC d1cbe790: Allocating the LinuxKPI current structure from an interrupt thread must be done using the M_NOWAIT flag after 1ae20f7c .
  MFC 6eb60f5b: Use the word "LinuxKPI" instead of "Linux compatibility", to not confuse with user-space Linux compatibility support. No functional change.
  MFC ebe5cf35: Implement basic support for allocating memory from a specific numa node in the LinuxKPI.
  MFC c743a6bd: Implement mallocarray_domainset(9) variant of mallocarray(9).
parents 3c97133f 961e7887
......@@ -1306,6 +1306,7 @@ MLINKS+=malloc.9 free.9 \
malloc.9 malloc_domainset.9 \
malloc.9 free_domain.9 \
malloc.9 mallocarray.9 \
malloc.9 mallocarray_domainset.9 \
malloc.9 MALLOC_DECLARE.9 \
malloc.9 MALLOC_DEFINE.9 \
malloc.9 realloc.9 \
......
......@@ -29,7 +29,7 @@
.\" $NetBSD: malloc.9,v 1.3 1996/11/11 00:05:11 lukem Exp $
.\" $FreeBSD$
.\"
.Dd August 28, 2020
.Dd March 6, 2021
.Dt MALLOC 9
.Os
.Sh NAME
......@@ -64,6 +64,8 @@
.In sys/domainset.h
.Ft void *
.Fn malloc_domainset "size_t size" "struct malloc_type *type" "struct domainset *ds" "int flags"
.Ft void *
.Fn mallocarray_domainset "size_t nmemb" "size_t size" "struct malloc_type *type" "struct domainset *ds" "int flags"
.Ft void
.Fn free_domain "void *addr" "struct malloc_type *type"
.Sh DESCRIPTION
......@@ -93,6 +95,15 @@ entries whose size is specified by
.Fa size .
.Pp
The
.Fn mallocarray_domainset
variant allocates memory from a specific
.Xr numa 4
domain using the specified domain selection policy.
See
.Xr domainset 9
for some example policies.
.Pp
The
.Fn free
function releases memory at address
.Fa addr
......
......@@ -35,11 +35,13 @@
#include <sys/proc.h>
#include <sys/malloc.h>
struct domainset;
struct thread;
struct task_struct;
extern int linux_alloc_current(struct thread *, int flags);
extern void linux_free_current(struct task_struct *);
extern struct domainset *linux_get_vm_domain_set(int node);
static inline void
linux_set_current(struct thread *td)
......
......@@ -555,11 +555,9 @@ class_remove_file(struct class *class, const struct class_attribute *attr)
sysfs_remove_file(&class->kobj, &attr->attr);
}
static inline int
dev_to_node(struct device *dev)
{
return -1;
}
#define dev_to_node(dev) linux_dev_to_node(dev)
#define of_node_to_nid(node) -1
int linux_dev_to_node(struct device *);
char *kvasprintf(gfp_t, const char *, va_list);
char *kasprintf(gfp_t, const char *, ...);
......
......@@ -2,7 +2,7 @@
* Copyright (c) 2010 Isilon Systems, Inc.
* Copyright (c) 2010 iX Systems, Inc.
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
* Copyright (c) 2013-2021 Mellanox Technologies, Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -37,6 +37,7 @@
#include <sys/limits.h>
#include <vm/uma.h>
#include <linux/compat.h>
#include <linux/types.h>
#include <linux/gfp.h>
......@@ -46,16 +47,15 @@ MALLOC_DECLARE(M_KMALLOC);
#define kvzalloc(size, flags) kmalloc(size, (flags) | __GFP_ZERO)
#define kvcalloc(n, size, flags) kvmalloc_array(n, size, (flags) | __GFP_ZERO)
#define kzalloc(size, flags) kmalloc(size, (flags) | __GFP_ZERO)
#define kzalloc_node(size, flags, node) kmalloc(size, (flags) | __GFP_ZERO)
#define kzalloc_node(size, flags, node) kmalloc_node(size, (flags) | __GFP_ZERO, node)
#define kfree_const(ptr) kfree(ptr)
#define vzalloc(size) __vmalloc(size, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, 0)
#define vfree(arg) kfree(arg)
#define kvfree(arg) kfree(arg)
#define vmalloc_node(size, node) __vmalloc(size, GFP_KERNEL, 0)
#define vmalloc_node(size, node) __vmalloc_node(size, GFP_KERNEL, node)
#define vmalloc_user(size) __vmalloc(size, GFP_KERNEL | __GFP_ZERO, 0)
#define vmalloc(size) __vmalloc(size, GFP_KERNEL, 0)
#define __kmalloc(...) kmalloc(__VA_ARGS__)
#define kmalloc_node(chunk, flags, n) kmalloc(chunk, flags)
/*
* Prefix some functions with linux_ to avoid namespace conflict
......@@ -111,6 +111,13 @@ kmalloc(size_t size, gfp_t flags)
return (malloc(size, M_KMALLOC, linux_check_m_flags(flags)));
}
static inline void *
kmalloc_node(size_t size, gfp_t flags, int node)
{
return (malloc_domainset(size, M_KMALLOC,
linux_get_vm_domain_set(node), linux_check_m_flags(flags)));
}
static inline void *
kcalloc(size_t n, size_t size, gfp_t flags)
{
......@@ -118,12 +125,27 @@ kcalloc(size_t n, size_t size, gfp_t flags)
return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags)));
}
static inline void *
kcalloc_node(size_t n, size_t size, gfp_t flags, int node)
{
flags |= __GFP_ZERO;
return (mallocarray_domainset(n, size, M_KMALLOC,
linux_get_vm_domain_set(node), linux_check_m_flags(flags)));
}
static inline void *
__vmalloc(size_t size, gfp_t flags, int other)
{
return (malloc(size, M_KMALLOC, linux_check_m_flags(flags)));
}
static inline void *
__vmalloc_node(size_t size, gfp_t flags, int node)
{
return (malloc_domainset(size, M_KMALLOC,
linux_get_vm_domain_set(node), linux_check_m_flags(flags)));
}
static inline void *
vmalloc_32(size_t size)
{
......@@ -136,6 +158,13 @@ kmalloc_array(size_t n, size_t size, gfp_t flags)
return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags)));
}
static inline void *
kmalloc_array_node(size_t n, size_t size, gfp_t flags, int node)
{
return (mallocarray_domainset(n, size, M_KMALLOC,
linux_get_vm_domain_set(node), linux_check_m_flags(flags)));
}
static inline void *
kvmalloc_array(size_t n, size_t size, gfp_t flags)
{
......
......@@ -1901,9 +1901,15 @@ linux_timer_callback_wrapper(void *context)
{
struct timer_list *timer;
linux_set_current(curthread);
timer = context;
if (linux_set_current_flags(curthread, M_NOWAIT)) {
/* try again later */
callout_reset(&timer->callout, 1,
&linux_timer_callback_wrapper, timer);
return;
}
timer->function(timer->data);
}
......@@ -2372,7 +2378,8 @@ linux_irq_handler(void *ent)
{
struct irq_ent *irqe;
linux_set_current(curthread);
if (linux_set_current_flags(curthread, M_NOWAIT))
return;
irqe = ent;
irqe->handler(irqe->irq, irqe->arg);
......
/*-
* Copyright (c) 2021 NVIDIA Networking
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/domainset.h>
#include <sys/bus.h>
#include <linux/compat.h>
#include <linux/device.h>
struct domainset *
linux_get_vm_domain_set(int node)
{
KASSERT(node < MAXMEMDOM, ("Invalid VM domain %d", node));
if (node < 0)
return (DOMAINSET_RR());
else
return (DOMAINSET_PREF(node));
}
int
linux_dev_to_node(struct device *dev)
{
int numa_domain;
if (dev == NULL || dev->bsddev == NULL ||
bus_get_domain(dev->bsddev, &numa_domain) != 0)
return (-1);
else
return (numa_domain);
}
......@@ -4552,6 +4552,8 @@ compat/linuxkpi/common/src/linux_compat.c optional compat_linuxkpi \
compile-with "${LINUXKPI_C}"
compat/linuxkpi/common/src/linux_current.c optional compat_linuxkpi \
compile-with "${LINUXKPI_C}"
compat/linuxkpi/common/src/linux_domain.c optional compat_linuxkpi \
compile-with "${LINUXKPI_C}"
compat/linuxkpi/common/src/linux_hrtimer.c optional compat_linuxkpi \
compile-with "${LINUXKPI_C}"
compat/linuxkpi/common/src/linux_kthread.c optional compat_linuxkpi \
......
......@@ -758,8 +758,8 @@ intr_handler_barrier(struct intr_handler *handler)
* Sleep until an ithread finishes executing an interrupt handler.
*
* XXX Doesn't currently handle interrupt filters or fast interrupt
* handlers. This is intended for compatibility with linux drivers
* only. Do not use in BSD code.
* handlers. This is intended for LinuxKPI drivers only.
* Do not use in BSD code.
*/
void
_intr_drain(int irq)
......
......@@ -699,6 +699,17 @@ mallocarray(size_t nmemb, size_t size, struct malloc_type *type, int flags)
return (malloc(size * nmemb, type, flags));
}
void *
mallocarray_domainset(size_t nmemb, size_t size, struct malloc_type *type,
struct domainset *ds, int flags)
{
if (WOULD_OVERFLOW(nmemb, size))
panic("mallocarray_domainset: %zu * %zu overflowed", nmemb, size);
return (malloc_domainset(size * nmemb, type, ds, flags));
}
#ifdef INVARIANTS
static void
free_save_type(void *addr, struct malloc_type *mtp, u_long size)
......
......@@ -4,6 +4,7 @@
KMOD= linuxkpi
SRCS= linux_compat.c \
linux_current.c \
linux_domain.c \
linux_hrtimer.c \
linux_idr.c \
linux_kmod.c \
......
......@@ -1466,6 +1466,39 @@ pf_pooladdr_to_kpooladdr(const struct pf_pooladdr *pool,
strlcpy(kpool->ifname, pool->ifname, sizeof(kpool->ifname));
}
static void
pf_kpool_to_pool(const struct pf_kpool *kpool, struct pf_pool *pool)
{
bzero(pool, sizeof(*pool));
bcopy(&kpool->key, &pool->key, sizeof(pool->key));
bcopy(&kpool->counter, &pool->counter, sizeof(pool->counter));
pool->tblidx = kpool->tblidx;
pool->proxy_port[0] = kpool->proxy_port[0];
pool->proxy_port[1] = kpool->proxy_port[1];
pool->opts = kpool->opts;
}
static int
pf_pool_to_kpool(const struct pf_pool *pool, struct pf_kpool *kpool)
{
_Static_assert(sizeof(pool->key) == sizeof(kpool->key), "");
_Static_assert(sizeof(pool->counter) == sizeof(kpool->counter), "");
bzero(kpool, sizeof(*kpool));
bcopy(&pool->key, &kpool->key, sizeof(kpool->key));
bcopy(&pool->counter, &kpool->counter, sizeof(kpool->counter));
kpool->tblidx = pool->tblidx;
kpool->proxy_port[0] = pool->proxy_port[0];
kpool->proxy_port[1] = pool->proxy_port[1];
kpool->opts = pool->opts;
return (0);
}
static void
pf_krule_to_rule(const struct pf_krule *krule, struct pf_rule *rule)
{
......@@ -1492,7 +1525,7 @@ pf_krule_to_rule(const struct pf_krule *krule, struct pf_rule *rule)
strlcpy(rule->overload_tblname, krule->overload_tblname,
sizeof(rule->overload_tblname));
bcopy(&krule->rpool, &rule->rpool, sizeof(krule->rpool));
pf_kpool_to_pool(&krule->rpool, &rule->rpool);
rule->evaluations = counter_u64_fetch(krule->evaluations);
for (int i = 0; i < 2; i++) {
......@@ -1629,7 +1662,9 @@ pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule)
strlcpy(krule->overload_tblname, rule->overload_tblname,
sizeof(rule->overload_tblname));
bcopy(&rule->rpool, &krule->rpool, sizeof(krule->rpool));
ret = pf_pool_to_kpool(&rule->rpool, &krule->rpool);
if (ret != 0)
return (ret);
/* Don't allow userspace to set evaulations, packets or bytes. */
/* kif, anchor, overload_tbl are not copied over. */
......
......@@ -192,7 +192,7 @@ int intr_event_resume_handler(void *cookie);
int intr_getaffinity(int irq, int mode, void *mask);
void *intr_handler_source(void *cookie);
int intr_setaffinity(int irq, int mode, void *mask);
void _intr_drain(int irq); /* Linux compat only. */
void _intr_drain(int irq); /* LinuxKPI only. */
int swi_add(struct intr_event **eventp, const char *name,
driver_intr_t handler, void *arg, int pri, enum intr_type flags,
void **cookiep);
......
......@@ -238,6 +238,9 @@ void *malloc_domainset(size_t size, struct malloc_type *type,
void *mallocarray(size_t nmemb, size_t size, struct malloc_type *type,
int flags) __malloc_like __result_use_check
__alloc_size2(1, 2);
void *mallocarray_domainset(size_t nmemb, size_t size, struct malloc_type *type,
struct domainset *ds, int flags) __malloc_like __result_use_check
__alloc_size2(1, 2);
void malloc_init(void *);
int malloc_last_fail(void);
void malloc_type_allocated(struct malloc_type *type, unsigned long size);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment