MFhead@r313398
This commit is contained in:
commit
951d93bc4b
@ -178,7 +178,7 @@ extern int YYPARSE_DECL();
|
||||
#define ID 257
|
||||
#define CONST 258
|
||||
#define YYERRCODE 256
|
||||
typedef short YYINT;
|
||||
typedef int YYINT;
|
||||
static const YYINT expr.oxout_lhs[] = { -1,
|
||||
2, 0, 1, 3, 3, 3, 3, 3, 3, 3,
|
||||
};
|
||||
|
@ -43,27 +43,3 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <arm/altera/socfpga/socfpga_rstmgr.h>
|
||||
|
||||
void
|
||||
cpu_reset(void)
|
||||
{
|
||||
uint32_t paddr;
|
||||
bus_addr_t vaddr;
|
||||
phandle_t node;
|
||||
|
||||
if (rstmgr_warmreset() == 0)
|
||||
goto end;
|
||||
|
||||
node = OF_finddevice("rstmgr");
|
||||
if (node == -1)
|
||||
goto end;
|
||||
|
||||
if ((OF_getencprop(node, "reg", &paddr, sizeof(paddr))) > 0) {
|
||||
if (bus_space_map(fdtbus_bs_tag, paddr, 0x8, 0, &vaddr) == 0) {
|
||||
bus_space_write_4(fdtbus_bs_tag, vaddr,
|
||||
RSTMGR_CTRL, CTRL_SWWARMRSTREQ);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
while (1);
|
||||
}
|
||||
|
@ -28,7 +28,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_platform.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
@ -41,38 +40,22 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <vm/vm.h>
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/fdt.h>
|
||||
#include <machine/machdep.h>
|
||||
#include <machine/platform.h>
|
||||
#include <machine/platformvar.h>
|
||||
|
||||
vm_offset_t
|
||||
platform_lastaddr(void)
|
||||
{
|
||||
#include <arm/altera/socfpga/socfpga_mp.h>
|
||||
#include <arm/altera/socfpga/socfpga_rstmgr.h>
|
||||
|
||||
return (devmap_lastaddr());
|
||||
}
|
||||
#include "platform_if.h"
|
||||
|
||||
void
|
||||
platform_probe_and_attach(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
platform_gpio_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
platform_late_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
platform_devmap_init(void)
|
||||
static int
|
||||
socfpga_devmap_init(platform_t plat)
|
||||
{
|
||||
|
||||
/* UART */
|
||||
@ -99,3 +82,42 @@ platform_devmap_init(void)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
socfpga_cpu_reset(platform_t plat)
|
||||
{
|
||||
uint32_t paddr;
|
||||
bus_addr_t vaddr;
|
||||
phandle_t node;
|
||||
|
||||
if (rstmgr_warmreset() == 0)
|
||||
goto end;
|
||||
|
||||
node = OF_finddevice("rstmgr");
|
||||
if (node == -1)
|
||||
goto end;
|
||||
|
||||
if ((OF_getencprop(node, "reg", &paddr, sizeof(paddr))) > 0) {
|
||||
if (bus_space_map(fdtbus_bs_tag, paddr, 0x8, 0, &vaddr) == 0) {
|
||||
bus_space_write_4(fdtbus_bs_tag, vaddr,
|
||||
RSTMGR_CTRL, CTRL_SWWARMRSTREQ);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
while (1);
|
||||
}
|
||||
|
||||
static platform_method_t socfpga_methods[] = {
|
||||
PLATFORMMETHOD(platform_devmap_init, socfpga_devmap_init),
|
||||
PLATFORMMETHOD(platform_cpu_reset, socfpga_cpu_reset),
|
||||
|
||||
#ifdef SMP
|
||||
PLATFORMMETHOD(platform_mp_setmaxid, socfpga_mp_setmaxid),
|
||||
PLATFORMMETHOD(platform_mp_start_ap, socfpga_mp_start_ap),
|
||||
#endif
|
||||
|
||||
PLATFORMMETHOD_END,
|
||||
};
|
||||
|
||||
FDT_PLATFORM_DEF(socfpga, "socfpga", 0, "altr,socfpga", 0);
|
||||
|
@ -28,6 +28,8 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "opt_platform.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
@ -45,6 +47,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/smp.h>
|
||||
#include <machine/fdt.h>
|
||||
#include <machine/intr.h>
|
||||
#include <machine/platformvar.h>
|
||||
|
||||
#include <arm/altera/socfpga/socfpga_mp.h>
|
||||
|
||||
#define SCU_PHYSBASE 0xFFFEC000
|
||||
#define SCU_SIZE 0x100
|
||||
@ -85,7 +90,7 @@ socfpga_trampoline(void)
|
||||
}
|
||||
|
||||
void
|
||||
platform_mp_setmaxid(void)
|
||||
socfpga_mp_setmaxid(platform_t plat)
|
||||
{
|
||||
int hwcpu, ncpu;
|
||||
|
||||
@ -105,7 +110,7 @@ platform_mp_setmaxid(void)
|
||||
}
|
||||
|
||||
void
|
||||
platform_mp_start_ap(void)
|
||||
socfpga_mp_start_ap(platform_t plat)
|
||||
{
|
||||
bus_space_handle_t scu, rst, ram;
|
||||
int reg;
|
||||
|
34
sys/arm/altera/socfpga/socfpga_mp.h
Normal file
34
sys/arm/altera/socfpga/socfpga_mp.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Andrew Turner <andrew@FreeBSD.org>
|
||||
* 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, 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _SOCFPGA_MP_H_
|
||||
#define _SOCFPGA_MP_H_
|
||||
|
||||
void socfpga_mp_setmaxid(platform_t);
|
||||
void socfpga_mp_start_ap(platform_t);
|
||||
|
||||
#endif /* _SOCFPGA_MP_H_ */
|
@ -26,6 +26,8 @@ makeoptions MODULES_OVERRIDE=""
|
||||
makeoptions WERROR="-Werror"
|
||||
|
||||
options SCHED_ULE # ULE scheduler
|
||||
options PLATFORM # Platform based SoC
|
||||
options PLATFORM_SMP
|
||||
options SMP # Enable multiple cores
|
||||
|
||||
# NFS root from boopt/dhcp
|
||||
|
@ -56,10 +56,12 @@ __FBSDID("$FreeBSD$");
|
||||
stp x0, x1, [sp, #(TF_X + 0 * 8)]
|
||||
mrs x10, elr_el1
|
||||
mrs x11, spsr_el1
|
||||
mrs x12, esr_el1
|
||||
.if \el == 0
|
||||
mrs x18, sp_el0
|
||||
.endif
|
||||
stp x10, x11, [sp, #(TF_ELR)]
|
||||
str x10, [sp, #(TF_ELR)]
|
||||
stp w11, w12, [sp, #(TF_SPSR)]
|
||||
stp x18, lr, [sp, #(TF_SP)]
|
||||
mrs x18, tpidr_el1
|
||||
add x29, sp, #(TF_SIZE)
|
||||
|
@ -62,4 +62,5 @@ ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
|
||||
ASSYM(TF_SIZE, sizeof(struct trapframe));
|
||||
ASSYM(TF_SP, offsetof(struct trapframe, tf_sp));
|
||||
ASSYM(TF_ELR, offsetof(struct trapframe, tf_elr));
|
||||
ASSYM(TF_SPSR, offsetof(struct trapframe, tf_spsr));
|
||||
ASSYM(TF_X, offsetof(struct trapframe, tf_x));
|
||||
|
@ -257,7 +257,7 @@ print_registers(struct trapframe *frame)
|
||||
printf(" sp: %16lx\n", frame->tf_sp);
|
||||
printf(" lr: %16lx\n", frame->tf_lr);
|
||||
printf(" elr: %16lx\n", frame->tf_elr);
|
||||
printf("spsr: %16lx\n", frame->tf_spsr);
|
||||
printf("spsr: %8x\n", frame->tf_spsr);
|
||||
}
|
||||
|
||||
void
|
||||
@ -267,7 +267,7 @@ do_el1h_sync(struct trapframe *frame)
|
||||
uint64_t esr, far;
|
||||
|
||||
/* Read the esr register to get the exception details */
|
||||
esr = READ_SPECIALREG(esr_el1);
|
||||
esr = frame->tf_esr;
|
||||
exception = ESR_ELx_EXCEPTION(esr);
|
||||
|
||||
#ifdef KDTRACE_HOOKS
|
||||
@ -352,7 +352,7 @@ do_el0_sync(struct trapframe *frame)
|
||||
td = curthread;
|
||||
td->td_frame = frame;
|
||||
|
||||
esr = READ_SPECIALREG(esr_el1);
|
||||
esr = frame->tf_esr;
|
||||
exception = ESR_ELx_EXCEPTION(esr);
|
||||
switch (exception) {
|
||||
case EXCP_UNKNOWN:
|
||||
|
@ -45,7 +45,8 @@ struct trapframe {
|
||||
uint64_t tf_sp;
|
||||
uint64_t tf_lr;
|
||||
uint64_t tf_elr;
|
||||
uint64_t tf_spsr;
|
||||
uint32_t tf_spsr;
|
||||
uint32_t tf_esr;
|
||||
uint64_t tf_x[30];
|
||||
};
|
||||
|
||||
|
@ -26,6 +26,7 @@ SRCS+= time_event.c
|
||||
# of a short. There's no good cast to use here so just ignore the
|
||||
# warnings for now.
|
||||
CWARNFLAGS.efinet.c+= -Wno-format
|
||||
CWARNFLAGS.efipart.c+= -Wno-format
|
||||
CWARNFLAGS.env.c+= -Wno-format
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "aarch64"
|
||||
|
@ -99,7 +99,7 @@ void mi_startup(void); /* Should be elsewhere */
|
||||
static struct session session0;
|
||||
static struct pgrp pgrp0;
|
||||
struct proc proc0;
|
||||
struct thread0_storage thread0_st __aligned(16);
|
||||
struct thread0_storage thread0_st __aligned(32);
|
||||
struct vmspace vmspace0;
|
||||
struct proc *initproc;
|
||||
|
||||
|
@ -140,63 +140,27 @@ struct lock_class lock_class_mtx_spin = {
|
||||
#ifdef ADAPTIVE_MUTEXES
|
||||
static SYSCTL_NODE(_debug, OID_AUTO, mtx, CTLFLAG_RD, NULL, "mtx debugging");
|
||||
|
||||
static struct lock_delay_config __read_mostly mtx_delay = {
|
||||
.initial = 1000,
|
||||
.step = 500,
|
||||
.min = 100,
|
||||
.max = 5000,
|
||||
};
|
||||
static struct lock_delay_config __read_mostly mtx_delay;
|
||||
|
||||
SYSCTL_INT(_debug_mtx, OID_AUTO, delay_initial, CTLFLAG_RW, &mtx_delay.initial,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_mtx, OID_AUTO, delay_step, CTLFLAG_RW, &mtx_delay.step,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_mtx, OID_AUTO, delay_min, CTLFLAG_RW, &mtx_delay.min,
|
||||
SYSCTL_INT(_debug_mtx, OID_AUTO, delay_base, CTLFLAG_RW, &mtx_delay.base,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_mtx, OID_AUTO, delay_max, CTLFLAG_RW, &mtx_delay.max,
|
||||
0, "");
|
||||
|
||||
static void
|
||||
mtx_delay_sysinit(void *dummy)
|
||||
{
|
||||
|
||||
mtx_delay.initial = mp_ncpus * 25;
|
||||
mtx_delay.step = (mp_ncpus * 25) / 2;
|
||||
mtx_delay.min = mp_ncpus * 5;
|
||||
mtx_delay.max = mp_ncpus * 25 * 10;
|
||||
}
|
||||
LOCK_DELAY_SYSINIT(mtx_delay_sysinit);
|
||||
LOCK_DELAY_SYSINIT_DEFAULT(mtx_delay);
|
||||
#endif
|
||||
|
||||
static SYSCTL_NODE(_debug, OID_AUTO, mtx_spin, CTLFLAG_RD, NULL,
|
||||
"mtx spin debugging");
|
||||
|
||||
static struct lock_delay_config __read_mostly mtx_spin_delay = {
|
||||
.initial = 1000,
|
||||
.step = 500,
|
||||
.min = 100,
|
||||
.max = 5000,
|
||||
};
|
||||
static struct lock_delay_config __read_mostly mtx_spin_delay;
|
||||
|
||||
SYSCTL_INT(_debug_mtx_spin, OID_AUTO, delay_initial, CTLFLAG_RW,
|
||||
&mtx_spin_delay.initial, 0, "");
|
||||
SYSCTL_INT(_debug_mtx_spin, OID_AUTO, delay_step, CTLFLAG_RW, &mtx_spin_delay.step,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_mtx_spin, OID_AUTO, delay_min, CTLFLAG_RW, &mtx_spin_delay.min,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_mtx_spin, OID_AUTO, delay_max, CTLFLAG_RW, &mtx_spin_delay.max,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_mtx_spin, OID_AUTO, delay_base, CTLFLAG_RW,
|
||||
&mtx_spin_delay.base, 0, "");
|
||||
SYSCTL_INT(_debug_mtx_spin, OID_AUTO, delay_max, CTLFLAG_RW,
|
||||
&mtx_spin_delay.max, 0, "");
|
||||
|
||||
static void
|
||||
mtx_spin_delay_sysinit(void *dummy)
|
||||
{
|
||||
|
||||
mtx_spin_delay.initial = mp_ncpus * 25;
|
||||
mtx_spin_delay.step = (mp_ncpus * 25) / 2;
|
||||
mtx_spin_delay.min = mp_ncpus * 5;
|
||||
mtx_spin_delay.max = mp_ncpus * 25 * 10;
|
||||
}
|
||||
LOCK_DELAY_SYSINIT(mtx_spin_delay_sysinit);
|
||||
LOCK_DELAY_SYSINIT_DEFAULT(mtx_spin_delay);
|
||||
|
||||
/*
|
||||
* System-wide mutexes
|
||||
|
@ -100,32 +100,14 @@ static SYSCTL_NODE(_debug, OID_AUTO, rwlock, CTLFLAG_RD, NULL,
|
||||
SYSCTL_INT(_debug_rwlock, OID_AUTO, retry, CTLFLAG_RW, &rowner_retries, 0, "");
|
||||
SYSCTL_INT(_debug_rwlock, OID_AUTO, loops, CTLFLAG_RW, &rowner_loops, 0, "");
|
||||
|
||||
static struct lock_delay_config __read_mostly rw_delay = {
|
||||
.initial = 1000,
|
||||
.step = 500,
|
||||
.min = 100,
|
||||
.max = 5000,
|
||||
};
|
||||
static struct lock_delay_config __read_mostly rw_delay;
|
||||
|
||||
SYSCTL_INT(_debug_rwlock, OID_AUTO, delay_initial, CTLFLAG_RW, &rw_delay.initial,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_rwlock, OID_AUTO, delay_step, CTLFLAG_RW, &rw_delay.step,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_rwlock, OID_AUTO, delay_min, CTLFLAG_RW, &rw_delay.min,
|
||||
SYSCTL_INT(_debug_rwlock, OID_AUTO, delay_base, CTLFLAG_RW, &rw_delay.base,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_rwlock, OID_AUTO, delay_max, CTLFLAG_RW, &rw_delay.max,
|
||||
0, "");
|
||||
|
||||
static void
|
||||
rw_delay_sysinit(void *dummy)
|
||||
{
|
||||
|
||||
rw_delay.initial = mp_ncpus * 25;
|
||||
rw_delay.step = (mp_ncpus * 25) / 2;
|
||||
rw_delay.min = mp_ncpus * 5;
|
||||
rw_delay.max = mp_ncpus * 25 * 10;
|
||||
}
|
||||
LOCK_DELAY_SYSINIT(rw_delay_sysinit);
|
||||
LOCK_DELAY_SYSINIT_DEFAULT(rw_delay);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -330,6 +312,7 @@ __rw_try_wlock(volatile uintptr_t *c, const char *file, int line)
|
||||
if (rw_wlocked(rw) &&
|
||||
(rw->lock_object.lo_flags & LO_RECURSABLE) != 0) {
|
||||
rw->rw_recurse++;
|
||||
atomic_set_ptr(&rw->rw_lock, RW_LOCK_WRITER_RECURSED);
|
||||
rval = 1;
|
||||
} else
|
||||
rval = atomic_cmpset_acq_ptr(&rw->rw_lock, RW_UNLOCKED,
|
||||
@ -363,10 +346,8 @@ _rw_wunlock_cookie(volatile uintptr_t *c, const char *file, int line)
|
||||
WITNESS_UNLOCK(&rw->lock_object, LOP_EXCLUSIVE, file, line);
|
||||
LOCK_LOG_LOCK("WUNLOCK", &rw->lock_object, 0, rw->rw_recurse, file,
|
||||
line);
|
||||
if (rw->rw_recurse)
|
||||
rw->rw_recurse--;
|
||||
else
|
||||
_rw_wunlock_hard(rw, (uintptr_t)curthread, file, line);
|
||||
|
||||
_rw_wunlock_hard(rw, (uintptr_t)curthread, file, line);
|
||||
|
||||
TD_LOCKS_DEC(curthread);
|
||||
}
|
||||
@ -820,6 +801,7 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
|
||||
("%s: recursing but non-recursive rw %s @ %s:%d\n",
|
||||
__func__, rw->lock_object.lo_name, file, line));
|
||||
rw->rw_recurse++;
|
||||
atomic_set_ptr(&rw->rw_lock, RW_LOCK_WRITER_RECURSED);
|
||||
if (LOCK_LOG_TEST(&rw->lock_object, 0))
|
||||
CTR2(KTR_LOCK, "%s: %p recursing", __func__, rw);
|
||||
return;
|
||||
@ -1012,12 +994,17 @@ __rw_wunlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
|
||||
return;
|
||||
|
||||
rw = rwlock2rw(c);
|
||||
MPASS(!rw_recursed(rw));
|
||||
|
||||
LOCKSTAT_PROFILE_RELEASE_RWLOCK(rw__release, rw,
|
||||
LOCKSTAT_WRITER);
|
||||
if (_rw_write_unlock(rw, tid))
|
||||
if (!rw_recursed(rw)) {
|
||||
LOCKSTAT_PROFILE_RELEASE_RWLOCK(rw__release, rw,
|
||||
LOCKSTAT_WRITER);
|
||||
if (_rw_write_unlock(rw, tid))
|
||||
return;
|
||||
} else {
|
||||
if (--(rw->rw_recurse) == 0)
|
||||
atomic_clear_ptr(&rw->rw_lock, RW_LOCK_WRITER_RECURSED);
|
||||
return;
|
||||
}
|
||||
|
||||
KASSERT(rw->rw_lock & (RW_LOCK_READ_WAITERS | RW_LOCK_WRITE_WAITERS),
|
||||
("%s: neither of the waiter flags are set", __func__));
|
||||
|
@ -148,32 +148,14 @@ static SYSCTL_NODE(_debug, OID_AUTO, sx, CTLFLAG_RD, NULL, "sxlock debugging");
|
||||
SYSCTL_UINT(_debug_sx, OID_AUTO, retries, CTLFLAG_RW, &asx_retries, 0, "");
|
||||
SYSCTL_UINT(_debug_sx, OID_AUTO, loops, CTLFLAG_RW, &asx_loops, 0, "");
|
||||
|
||||
static struct lock_delay_config __read_mostly sx_delay = {
|
||||
.initial = 1000,
|
||||
.step = 500,
|
||||
.min = 100,
|
||||
.max = 5000,
|
||||
};
|
||||
static struct lock_delay_config __read_mostly sx_delay;
|
||||
|
||||
SYSCTL_INT(_debug_sx, OID_AUTO, delay_initial, CTLFLAG_RW, &sx_delay.initial,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_sx, OID_AUTO, delay_step, CTLFLAG_RW, &sx_delay.step,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_sx, OID_AUTO, delay_min, CTLFLAG_RW, &sx_delay.min,
|
||||
SYSCTL_INT(_debug_sx, OID_AUTO, delay_base, CTLFLAG_RW, &sx_delay.base,
|
||||
0, "");
|
||||
SYSCTL_INT(_debug_sx, OID_AUTO, delay_max, CTLFLAG_RW, &sx_delay.max,
|
||||
0, "");
|
||||
|
||||
static void
|
||||
sx_delay_sysinit(void *dummy)
|
||||
{
|
||||
|
||||
sx_delay.initial = mp_ncpus * 25;
|
||||
sx_delay.step = (mp_ncpus * 25) / 2;
|
||||
sx_delay.min = mp_ncpus * 5;
|
||||
sx_delay.max = mp_ncpus * 25 * 10;
|
||||
}
|
||||
LOCK_DELAY_SYSINIT(sx_delay_sysinit);
|
||||
LOCK_DELAY_SYSINIT_DEFAULT(sx_delay);
|
||||
#endif
|
||||
|
||||
void
|
||||
|
@ -281,7 +281,7 @@ threadinit(void)
|
||||
|
||||
thread_zone = uma_zcreate("THREAD", sched_sizeof_thread(),
|
||||
thread_ctor, thread_dtor, thread_init, thread_fini,
|
||||
16 - 1, UMA_ZONE_NOFREE);
|
||||
32 - 1, UMA_ZONE_NOFREE);
|
||||
tidhashtbl = hashinit(maxproc / 2, M_TIDHASH, &tidhash);
|
||||
rw_init(&tidhash_lock, "tidhash");
|
||||
}
|
||||
|
@ -56,6 +56,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
SDT_PROVIDER_DEFINE(lock);
|
||||
SDT_PROBE_DEFINE1(lock, , , starvation, "u_int");
|
||||
|
||||
CTASSERT(LOCK_CLASS_MAX == 15);
|
||||
|
||||
struct lock_class *lock_classes[LOCK_CLASS_MAX + 1] = {
|
||||
@ -103,32 +106,56 @@ lock_destroy(struct lock_object *lock)
|
||||
lock->lo_flags &= ~LO_INITIALIZED;
|
||||
}
|
||||
|
||||
static SYSCTL_NODE(_debug, OID_AUTO, lock, CTLFLAG_RD, NULL, "lock debugging");
|
||||
static SYSCTL_NODE(_debug_lock, OID_AUTO, delay, CTLFLAG_RD, NULL,
|
||||
"lock delay");
|
||||
|
||||
static u_int __read_mostly starvation_limit = 131072;
|
||||
SYSCTL_INT(_debug_lock_delay, OID_AUTO, starvation_limit, CTLFLAG_RW,
|
||||
&starvation_limit, 0, "");
|
||||
|
||||
static u_int __read_mostly restrict_starvation = 0;
|
||||
SYSCTL_INT(_debug_lock_delay, OID_AUTO, restrict_starvation, CTLFLAG_RW,
|
||||
&restrict_starvation, 0, "");
|
||||
|
||||
void
|
||||
lock_delay(struct lock_delay_arg *la)
|
||||
{
|
||||
u_int i, delay, backoff, min, max;
|
||||
struct lock_delay_config *lc = la->config;
|
||||
u_int i;
|
||||
|
||||
delay = la->delay;
|
||||
la->delay <<= 1;
|
||||
if (__predict_false(la->delay > lc->max))
|
||||
la->delay = lc->max;
|
||||
|
||||
if (delay == 0)
|
||||
delay = lc->initial;
|
||||
else {
|
||||
delay += lc->step;
|
||||
max = lc->max;
|
||||
if (delay > max)
|
||||
delay = max;
|
||||
}
|
||||
|
||||
backoff = cpu_ticks() % delay;
|
||||
min = lc->min;
|
||||
if (backoff < min)
|
||||
backoff = min;
|
||||
for (i = 0; i < backoff; i++)
|
||||
for (i = la->delay; i > 0; i--)
|
||||
cpu_spinwait();
|
||||
|
||||
la->delay = delay;
|
||||
la->spin_cnt += backoff;
|
||||
la->spin_cnt += la->delay;
|
||||
if (__predict_false(la->spin_cnt > starvation_limit)) {
|
||||
SDT_PROBE1(lock, , , starvation, la->delay);
|
||||
if (restrict_starvation)
|
||||
la->delay = lc->base;
|
||||
}
|
||||
}
|
||||
|
||||
static u_int
|
||||
lock_roundup_2(u_int val)
|
||||
{
|
||||
u_int res;
|
||||
|
||||
for (res = 1; res <= val; res <<= 1)
|
||||
continue;
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
void
|
||||
lock_delay_default_init(struct lock_delay_config *lc)
|
||||
{
|
||||
|
||||
lc->base = lock_roundup_2(mp_ncpus) / 4;
|
||||
lc->max = lc->base * 1024;
|
||||
}
|
||||
|
||||
#ifdef DDB
|
||||
@ -655,7 +682,6 @@ lock_profile_release_lock(struct lock_object *lo)
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
static SYSCTL_NODE(_debug, OID_AUTO, lock, CTLFLAG_RD, NULL, "lock debugging");
|
||||
static SYSCTL_NODE(_debug_lock, OID_AUTO, prof, CTLFLAG_RD, NULL,
|
||||
"lock profiling");
|
||||
SYSCTL_INT(_debug_lock_prof, OID_AUTO, skipspin, CTLFLAG_RW,
|
||||
|
@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sf_buf.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
@ -1,17 +1,26 @@
|
||||
# $FreeBSD$
|
||||
# All the dts files for allwinner systems we support.
|
||||
DTS= \
|
||||
bananapi.dts \
|
||||
bananapim2.dts \
|
||||
cubieboard.dts \
|
||||
cubieboard2.dts \
|
||||
nanopi-neo.dts \
|
||||
olimex-a20-som-evb.dts \
|
||||
olinuxino-lime.dts \
|
||||
orangepi-plus-2e.dts \
|
||||
pcduino3.dts \
|
||||
sinovoip-bpi-m3.dts \
|
||||
sun4i-a10-cubieboard.dts \
|
||||
sun4i-a10-olinuxino-lime.dts \
|
||||
sun6i-a31s-sinovoip-bpi-m2.dts \
|
||||
sun5i-a13-olinuxino.dts \
|
||||
sun5i-r8-chip.dts
|
||||
sun5i-r8-chip.dts \
|
||||
sun7i-a20-bananapi.dts \
|
||||
sun7i-a20-cubieboard2.dts \
|
||||
sun7i-a20-olimex-som-evb.dts \
|
||||
sun7i-a20-pcduino3.dts
|
||||
|
||||
LINKS= \
|
||||
${DTBDIR}/sun4i-a10-cubieboard.dtb ${DTBDIR}/cubieboard.dtb \
|
||||
${DTBDIR}/sun4i-a10-olinuxino-lime.dtb ${DTBDIR}/olinuxino-lime.dtb \
|
||||
${DTBDIR}/sun6i-a31s-sinovoip-bpi-m2.dtb ${DTBDIR}/bananapim2.dtb \
|
||||
${DTBDIR}/sun7i-a20-bananapi.dtb ${DTBDIR}/bananapi.dtb \
|
||||
${DTBDIR}/sun7i-a20-cubieboard2.dtb ${DTBDIR}/cubieboard2.dtb \
|
||||
${DTBDIR}/sun7i-a20-olimex-som-evb.dtb ${DTBDIR}/olimex-a20-som-evb.dtb \
|
||||
${DTBDIR}/sun7i-a20-pcduino3.dtb ${DTBDIR}/pcduino3.dtb
|
||||
|
||||
.include <bsd.dtb.mk>
|
||||
|
@ -202,9 +202,7 @@ extern struct lock_class lock_class_lockmgr;
|
||||
extern struct lock_class *lock_classes[];
|
||||
|
||||
struct lock_delay_config {
|
||||
u_int initial;
|
||||
u_int step;
|
||||
u_int min;
|
||||
u_int base;
|
||||
u_int max;
|
||||
};
|
||||
|
||||
@ -215,19 +213,25 @@ struct lock_delay_arg {
|
||||
};
|
||||
|
||||
static inline void
|
||||
lock_delay_arg_init(struct lock_delay_arg *la, struct lock_delay_config *lc) {
|
||||
lock_delay_arg_init(struct lock_delay_arg *la, struct lock_delay_config *lc)
|
||||
{
|
||||
la->config = lc;
|
||||
la->delay = 0;
|
||||
la->delay = lc->base;
|
||||
la->spin_cnt = 0;
|
||||
}
|
||||
|
||||
#define LOCK_DELAY_SYSINIT(func) \
|
||||
SYSINIT(func##_ld, SI_SUB_LOCK, SI_ORDER_ANY, func, NULL)
|
||||
|
||||
#define LOCK_DELAY_SYSINIT_DEFAULT(lc) \
|
||||
SYSINIT(lock_delay_##lc##_ld, SI_SUB_LOCK, SI_ORDER_ANY, \
|
||||
lock_delay_default_init, &lc)
|
||||
|
||||
void lock_init(struct lock_object *, struct lock_class *,
|
||||
const char *, const char *, int);
|
||||
void lock_destroy(struct lock_object *);
|
||||
void lock_delay(struct lock_delay_arg *);
|
||||
void lock_delay_default_init(struct lock_delay_config *);
|
||||
void spinlock_enter(void);
|
||||
void spinlock_exit(void);
|
||||
void witness_init(struct lock_object *, const char *);
|
||||
|
@ -58,9 +58,10 @@
|
||||
#define RW_LOCK_READ_WAITERS 0x02
|
||||
#define RW_LOCK_WRITE_WAITERS 0x04
|
||||
#define RW_LOCK_WRITE_SPINNER 0x08
|
||||
#define RW_LOCK_WRITER_RECURSED 0x10
|
||||
#define RW_LOCK_FLAGMASK \
|
||||
(RW_LOCK_READ | RW_LOCK_READ_WAITERS | RW_LOCK_WRITE_WAITERS | \
|
||||
RW_LOCK_WRITE_SPINNER)
|
||||
RW_LOCK_WRITE_SPINNER | RW_LOCK_WRITER_RECURSED)
|
||||
#define RW_LOCK_WAITERS (RW_LOCK_READ_WAITERS | RW_LOCK_WRITE_WAITERS)
|
||||
|
||||
#define RW_OWNER(x) ((x) & ~RW_LOCK_FLAGMASK)
|
||||
@ -111,13 +112,9 @@
|
||||
#define __rw_wunlock(rw, tid, file, line) do { \
|
||||
uintptr_t _tid = (uintptr_t)(tid); \
|
||||
\
|
||||
if ((rw)->rw_recurse) \
|
||||
(rw)->rw_recurse--; \
|
||||
else { \
|
||||
if (__predict_false(LOCKSTAT_PROFILE_ENABLED(rw__release) ||\
|
||||
!_rw_write_unlock((rw), _tid))) \
|
||||
_rw_wunlock_hard((rw), _tid, (file), (line)); \
|
||||
} \
|
||||
if (__predict_false(LOCKSTAT_PROFILE_ENABLED(rw__release) || \
|
||||
!_rw_write_unlock((rw), _tid))) \
|
||||
_rw_wunlock_hard((rw), _tid, (file), (line)); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
|
@ -595,6 +595,61 @@ udp_dontroute_cleanup()
|
||||
cleanup_tap
|
||||
}
|
||||
|
||||
atf_test_case udp_dontroute6 cleanup
|
||||
udp_dontroute6_head()
|
||||
{
|
||||
atf_set "descr" "Source address selection for UDP IPv6 packets with SO_DONTROUTE on non-default FIBs works"
|
||||
atf_set "require.user" "root"
|
||||
atf_set "require.config" "fibs"
|
||||
}
|
||||
|
||||
udp_dontroute6_body()
|
||||
{
|
||||
# Configure the TAP interface to use an RFC3849 nonrouteable address
|
||||
# and a non-default fib
|
||||
ADDR0="2001:db8::2"
|
||||
ADDR1="2001:db8::3"
|
||||
SUBNET="2001:db8::"
|
||||
MASK="64"
|
||||
# Use a different IP on the same subnet as the target
|
||||
TARGET="2001:db8::100"
|
||||
SRCDIR=`atf_get_srcdir`
|
||||
|
||||
atf_expect_fail "PR196361 IPv6 network routes don't respect net.add_addr_allfibs=0"
|
||||
|
||||
# Check system configuration
|
||||
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
|
||||
atf_skip "This test requires net.add_addr_allfibs=0"
|
||||
fi
|
||||
get_fibs 2
|
||||
|
||||
# Configure the TAP interfaces. Use no_dad so the addresses will be
|
||||
# ready right away and won't be marked as tentative until DAD
|
||||
# completes.
|
||||
setup_tap ${FIB0} inet6 ${ADDR0} ${MASK} no_dad
|
||||
TARGET_TAP=${TAP}
|
||||
setup_tap ${FIB1} inet6 ${ADDR1} ${MASK} no_dad
|
||||
|
||||
# Send a UDP packet with SO_DONTROUTE. In the failure case, it will
|
||||
# return ENETUNREACH, or send the packet to the wrong tap
|
||||
atf_check -o ignore setfib ${FIB0} \
|
||||
${SRCDIR}/udp_dontroute -6 ${TARGET} /dev/${TARGET_TAP}
|
||||
cleanup_tap
|
||||
|
||||
# Repeat, but this time target the other tap
|
||||
setup_tap ${FIB0} inet6 ${ADDR0} ${MASK} no_dad
|
||||
setup_tap ${FIB1} inet6 ${ADDR1} ${MASK} no_dad
|
||||
TARGET_TAP=${TAP}
|
||||
|
||||
atf_check -o ignore setfib ${FIB1} \
|
||||
${SRCDIR}/udp_dontroute -6 ${TARGET} /dev/${TARGET_TAP}
|
||||
}
|
||||
|
||||
udp_dontroute6_cleanup()
|
||||
{
|
||||
cleanup_tap
|
||||
}
|
||||
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
@ -609,6 +664,7 @@ atf_init_test_cases()
|
||||
atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet
|
||||
atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6
|
||||
atf_add_test_case udp_dontroute
|
||||
atf_add_test_case udp_dontroute6
|
||||
}
|
||||
|
||||
# Looks up one or more fibs from the configuration data and validates them.
|
||||
@ -656,6 +712,7 @@ get_tap()
|
||||
# Protocol (inet or inet6)
|
||||
# IP address
|
||||
# Netmask in number of bits (eg 24 or 8)
|
||||
# Extra flags
|
||||
# Return: the tap interface name as the env variable TAP
|
||||
setup_tap()
|
||||
{
|
||||
@ -663,9 +720,10 @@ setup_tap()
|
||||
local PROTO=$2
|
||||
local ADDR=$3
|
||||
local MASK=$4
|
||||
local FLAGS=$5
|
||||
get_tap
|
||||
echo setfib ${FIB} ifconfig $TAP ${PROTO} ${ADDR}/${MASK} fib $FIB
|
||||
setfib ${FIB} ifconfig $TAP ${PROTO} ${ADDR}/${MASK} fib $FIB
|
||||
echo setfib ${FIB} ifconfig $TAP ${PROTO} ${ADDR}/${MASK} fib $FIB $FLAGS
|
||||
setfib ${FIB} ifconfig $TAP ${PROTO} ${ADDR}/${MASK} fib $FIB $FLAGS
|
||||
}
|
||||
|
||||
cleanup_tap()
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -52,7 +53,7 @@
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_in dst;
|
||||
struct sockaddr_storage dst;
|
||||
int s, t;
|
||||
int opt;
|
||||
int ret;
|
||||
@ -60,17 +61,33 @@ main(int argc, char **argv)
|
||||
const char* sendbuf = "Hello, World!";
|
||||
const size_t buflen = 80;
|
||||
char recvbuf[buflen];
|
||||
bool v6 = false;
|
||||
const char *addr, *tapdev;
|
||||
const uint16_t port = 46120;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s ip_address tapdev\n", argv[0]);
|
||||
bzero(&dst, sizeof(dst));
|
||||
if (argc < 3 || argc > 4) {
|
||||
fprintf(stderr, "Usage: %s [-6] ip_address tapdev\n", argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
t = open(argv[2], O_RDWR | O_NONBLOCK);
|
||||
if (strcmp("-6", argv[1]) == 0) {
|
||||
v6 = true;
|
||||
addr = argv[2];
|
||||
tapdev = argv[3];
|
||||
} else {
|
||||
addr = argv[1];
|
||||
tapdev = argv[2];
|
||||
}
|
||||
|
||||
t = open(tapdev, O_RDWR | O_NONBLOCK);
|
||||
if (t < 0)
|
||||
err(EXIT_FAILURE, "open");
|
||||
|
||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (v6)
|
||||
s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
else
|
||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0)
|
||||
err(EXIT_FAILURE, "socket");
|
||||
opt = 1;
|
||||
@ -79,16 +96,26 @@ main(int argc, char **argv)
|
||||
if (ret == -1)
|
||||
err(EXIT_FAILURE, "setsockopt(SO_DONTROUTE)");
|
||||
|
||||
dst.sin_len = sizeof(dst);
|
||||
dst.sin_family = AF_INET;
|
||||
dst.sin_port = htons(46120);
|
||||
dst.sin_addr.s_addr = inet_addr(argv[1]);
|
||||
if (dst.sin_addr.s_addr == htonl(INADDR_NONE)) {
|
||||
fprintf(stderr, "Invalid address: %s\n", argv[1]);
|
||||
exit(2);
|
||||
if (v6) {
|
||||
struct sockaddr_in6 *dst6 = ((struct sockaddr_in6*)&dst);
|
||||
|
||||
dst.ss_len = sizeof(struct sockaddr_in6);
|
||||
dst.ss_family = AF_INET6;
|
||||
dst6->sin6_port = htons(port);
|
||||
ret = inet_pton(AF_INET6, addr, &dst6->sin6_addr);
|
||||
} else {
|
||||
struct sockaddr_in *dst4 = ((struct sockaddr_in*)&dst);
|
||||
|
||||
dst.ss_len = sizeof(struct sockaddr_in);
|
||||
dst.ss_family = AF_INET;
|
||||
dst4->sin_port = htons(port);
|
||||
ret = inet_pton(AF_INET, addr, &dst4->sin_addr);
|
||||
}
|
||||
if (ret != 1)
|
||||
err(EXIT_FAILURE, "inet_pton returned %d", ret);
|
||||
|
||||
ret = sendto(s, sendbuf, strlen(sendbuf), 0, (struct sockaddr*)&dst,
|
||||
dst.sin_len);
|
||||
dst.ss_len);
|
||||
if (ret == -1)
|
||||
err(EXIT_FAILURE, "sendto");
|
||||
|
||||
|
@ -47,8 +47,6 @@ inplace_symlink_src_head()
|
||||
}
|
||||
inplace_symlink_src_body()
|
||||
{
|
||||
atf_expect_fail "Check for S_IFREG reverted in r312404"
|
||||
|
||||
echo foo > a
|
||||
atf_check ln -s a b
|
||||
atf_check -e not-empty -s not-exit:0 sed -i '' -e 's,foo,bar,g' b
|
||||
|
Loading…
Reference in New Issue
Block a user