mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-05-14 04:29:18 +08:00
Avoid per-CPU features
This commit is contained in:
parent
e3dd7a480e
commit
937461c950
1
Makefile
1
Makefile
@ -375,7 +375,6 @@ C_FILES += freebsd/kern/subr_hints.c
|
||||
C_FILES += freebsd/dev/random/harvest.c
|
||||
C_FILES += freebsd/libkern/random.c
|
||||
C_FILES += freebsd/libkern/arc4random.c
|
||||
C_FILES += freebsd/kern/subr_pcpu.c
|
||||
C_FILES += freebsd/kern/subr_sbuf.c
|
||||
C_FILES += freebsd/kern/subr_rman.c
|
||||
C_FILES += freebsd/kern/subr_module.c
|
||||
|
@ -1391,7 +1391,6 @@ devNic.addSourceFiles(
|
||||
'dev/random/harvest.c',
|
||||
'libkern/random.c',
|
||||
'libkern/arc4random.c',
|
||||
'kern/subr_pcpu.c',
|
||||
'kern/subr_sbuf.c',
|
||||
'kern/subr_rman.c',
|
||||
'kern/subr_module.c',
|
||||
|
@ -1,409 +0,0 @@
|
||||
#include <freebsd/machine/rtems-bsd-config.h>
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 Wind River Systems, Inc.
|
||||
* All rights reserved.
|
||||
* Written by: John Baldwin <jhb@FreeBSD.org>
|
||||
*
|
||||
* Copyright (c) 2009 Jeffrey Roberson <jeff@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.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This module provides MI support for per-cpu data.
|
||||
*
|
||||
* Each architecture determines the mapping of logical CPU IDs to physical
|
||||
* CPUs. The requirements of this mapping are as follows:
|
||||
* - Logical CPU IDs must reside in the range 0 ... MAXCPU - 1.
|
||||
* - The mapping is not required to be dense. That is, there may be
|
||||
* gaps in the mappings.
|
||||
* - The platform sets the value of MAXCPU in <machine/param.h>.
|
||||
* - It is suggested, but not required, that in the non-SMP case, the
|
||||
* platform define MAXCPU to be 1 and define the logical ID of the
|
||||
* sole CPU as 0.
|
||||
*/
|
||||
|
||||
#include <freebsd/sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <freebsd/local/opt_ddb.h>
|
||||
|
||||
#include <freebsd/sys/param.h>
|
||||
#include <freebsd/sys/systm.h>
|
||||
#include <freebsd/sys/sysctl.h>
|
||||
#include <freebsd/sys/linker_set.h>
|
||||
#include <freebsd/sys/lock.h>
|
||||
#include <freebsd/sys/malloc.h>
|
||||
#include <freebsd/sys/pcpu.h>
|
||||
#include <freebsd/sys/proc.h>
|
||||
#include <freebsd/sys/smp.h>
|
||||
#include <freebsd/sys/sx.h>
|
||||
#include <freebsd/ddb/ddb.h>
|
||||
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/kernel.h>
|
||||
#endif
|
||||
|
||||
MALLOC_DEFINE(M_PCPU, "Per-cpu", "Per-cpu resource accouting.");
|
||||
|
||||
struct dpcpu_free {
|
||||
uintptr_t df_start;
|
||||
int df_len;
|
||||
TAILQ_ENTRY(dpcpu_free) df_link;
|
||||
};
|
||||
|
||||
static DPCPU_DEFINE(char, modspace[DPCPU_MODMIN]);
|
||||
static TAILQ_HEAD(, dpcpu_free) dpcpu_head = TAILQ_HEAD_INITIALIZER(dpcpu_head);
|
||||
static struct sx dpcpu_lock;
|
||||
uintptr_t dpcpu_off[MAXCPU];
|
||||
struct pcpu *cpuid_to_pcpu[MAXCPU];
|
||||
struct cpuhead cpuhead = SLIST_HEAD_INITIALIZER(cpuhead);
|
||||
|
||||
/*
|
||||
* Initialize the MI portions of a struct pcpu.
|
||||
*/
|
||||
void
|
||||
pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
|
||||
{
|
||||
|
||||
bzero(pcpu, size);
|
||||
KASSERT(cpuid >= 0 && cpuid < MAXCPU,
|
||||
("pcpu_init: invalid cpuid %d", cpuid));
|
||||
pcpu->pc_cpuid = cpuid;
|
||||
pcpu->pc_cpumask = 1 << cpuid;
|
||||
cpuid_to_pcpu[cpuid] = pcpu;
|
||||
SLIST_INSERT_HEAD(&cpuhead, pcpu, pc_allcpu);
|
||||
#ifndef __rtems__
|
||||
cpu_pcpu_init(pcpu, cpuid, size);
|
||||
#endif
|
||||
pcpu->pc_rm_queue.rmq_next = &pcpu->pc_rm_queue;
|
||||
pcpu->pc_rm_queue.rmq_prev = &pcpu->pc_rm_queue;
|
||||
#ifdef KTR
|
||||
snprintf(pcpu->pc_name, sizeof(pcpu->pc_name), "CPU %d", cpuid);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
dpcpu_init(void *dpcpu, int cpuid)
|
||||
{
|
||||
struct pcpu *pcpu;
|
||||
|
||||
pcpu = pcpu_find(cpuid);
|
||||
pcpu->pc_dynamic = (uintptr_t)dpcpu - DPCPU_START;
|
||||
|
||||
/*
|
||||
* Initialize defaults from our linker section.
|
||||
*/
|
||||
memcpy(dpcpu, (void *)DPCPU_START, DPCPU_BYTES);
|
||||
|
||||
/*
|
||||
* Place it in the global pcpu offset array.
|
||||
*/
|
||||
dpcpu_off[cpuid] = pcpu->pc_dynamic;
|
||||
}
|
||||
|
||||
static void
|
||||
dpcpu_startup(void *dummy __unused)
|
||||
{
|
||||
struct dpcpu_free *df;
|
||||
|
||||
df = malloc(sizeof(*df), M_PCPU, M_WAITOK | M_ZERO);
|
||||
df->df_start = (uintptr_t)&DPCPU_NAME(modspace);
|
||||
df->df_len = DPCPU_MODMIN;
|
||||
TAILQ_INSERT_HEAD(&dpcpu_head, df, df_link);
|
||||
sx_init(&dpcpu_lock, "dpcpu alloc lock");
|
||||
}
|
||||
SYSINIT(dpcpu, SI_SUB_KLD, SI_ORDER_FIRST, dpcpu_startup, 0);
|
||||
|
||||
/*
|
||||
* First-fit extent based allocator for allocating space in the per-cpu
|
||||
* region reserved for modules. This is only intended for use by the
|
||||
* kernel linkers to place module linker sets.
|
||||
*/
|
||||
void *
|
||||
dpcpu_alloc(int size)
|
||||
{
|
||||
struct dpcpu_free *df;
|
||||
void *s;
|
||||
|
||||
s = NULL;
|
||||
size = roundup2(size, sizeof(void *));
|
||||
sx_xlock(&dpcpu_lock);
|
||||
TAILQ_FOREACH(df, &dpcpu_head, df_link) {
|
||||
if (df->df_len < size)
|
||||
continue;
|
||||
if (df->df_len == size) {
|
||||
s = (void *)df->df_start;
|
||||
TAILQ_REMOVE(&dpcpu_head, df, df_link);
|
||||
free(df, M_PCPU);
|
||||
break;
|
||||
}
|
||||
s = (void *)df->df_start;
|
||||
df->df_len -= size;
|
||||
df->df_start = df->df_start + size;
|
||||
break;
|
||||
}
|
||||
sx_xunlock(&dpcpu_lock);
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free dynamic per-cpu space at module unload time.
|
||||
*/
|
||||
void
|
||||
dpcpu_free(void *s, int size)
|
||||
{
|
||||
struct dpcpu_free *df;
|
||||
struct dpcpu_free *dn;
|
||||
uintptr_t start;
|
||||
uintptr_t end;
|
||||
|
||||
size = roundup2(size, sizeof(void *));
|
||||
start = (uintptr_t)s;
|
||||
end = start + size;
|
||||
/*
|
||||
* Free a region of space and merge it with as many neighbors as
|
||||
* possible. Keeping the list sorted simplifies this operation.
|
||||
*/
|
||||
sx_xlock(&dpcpu_lock);
|
||||
TAILQ_FOREACH(df, &dpcpu_head, df_link) {
|
||||
if (df->df_start > end)
|
||||
break;
|
||||
/*
|
||||
* If we expand at the end of an entry we may have to
|
||||
* merge it with the one following it as well.
|
||||
*/
|
||||
if (df->df_start + df->df_len == start) {
|
||||
df->df_len += size;
|
||||
dn = TAILQ_NEXT(df, df_link);
|
||||
if (df->df_start + df->df_len == dn->df_start) {
|
||||
df->df_len += dn->df_len;
|
||||
TAILQ_REMOVE(&dpcpu_head, dn, df_link);
|
||||
free(dn, M_PCPU);
|
||||
}
|
||||
sx_xunlock(&dpcpu_lock);
|
||||
return;
|
||||
}
|
||||
if (df->df_start == end) {
|
||||
df->df_start = start;
|
||||
df->df_len += size;
|
||||
sx_xunlock(&dpcpu_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
dn = malloc(sizeof(*df), M_PCPU, M_WAITOK | M_ZERO);
|
||||
dn->df_start = start;
|
||||
dn->df_len = size;
|
||||
if (df)
|
||||
TAILQ_INSERT_BEFORE(df, dn, df_link);
|
||||
else
|
||||
TAILQ_INSERT_TAIL(&dpcpu_head, dn, df_link);
|
||||
sx_xunlock(&dpcpu_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the per-cpu storage from an updated linker-set region.
|
||||
*/
|
||||
void
|
||||
dpcpu_copy(void *s, int size)
|
||||
{
|
||||
#ifdef SMP
|
||||
uintptr_t dpcpu;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mp_ncpus; ++i) {
|
||||
dpcpu = dpcpu_off[i];
|
||||
if (dpcpu == 0)
|
||||
continue;
|
||||
memcpy((void *)(dpcpu + (uintptr_t)s), s, size);
|
||||
}
|
||||
#else
|
||||
memcpy((void *)(dpcpu_off[0] + (uintptr_t)s), s, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a struct pcpu.
|
||||
*/
|
||||
void
|
||||
pcpu_destroy(struct pcpu *pcpu)
|
||||
{
|
||||
|
||||
SLIST_REMOVE(&cpuhead, pcpu, pcpu, pc_allcpu);
|
||||
cpuid_to_pcpu[pcpu->pc_cpuid] = NULL;
|
||||
dpcpu_off[pcpu->pc_cpuid] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate a struct pcpu by cpu id.
|
||||
*/
|
||||
struct pcpu *
|
||||
pcpu_find(u_int cpuid)
|
||||
{
|
||||
|
||||
return (cpuid_to_pcpu[cpuid]);
|
||||
}
|
||||
|
||||
int
|
||||
sysctl_dpcpu_quad(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
uintptr_t dpcpu;
|
||||
int64_t count;
|
||||
int i;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < mp_ncpus; ++i) {
|
||||
dpcpu = dpcpu_off[i];
|
||||
if (dpcpu == 0)
|
||||
continue;
|
||||
count += *(int64_t *)(dpcpu + (uintptr_t)arg1);
|
||||
}
|
||||
return (SYSCTL_OUT(req, &count, sizeof(count)));
|
||||
}
|
||||
|
||||
int
|
||||
sysctl_dpcpu_long(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
uintptr_t dpcpu;
|
||||
long count;
|
||||
int i;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < mp_ncpus; ++i) {
|
||||
dpcpu = dpcpu_off[i];
|
||||
if (dpcpu == 0)
|
||||
continue;
|
||||
count += *(long *)(dpcpu + (uintptr_t)arg1);
|
||||
}
|
||||
return (SYSCTL_OUT(req, &count, sizeof(count)));
|
||||
}
|
||||
|
||||
int
|
||||
sysctl_dpcpu_int(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
uintptr_t dpcpu;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < mp_ncpus; ++i) {
|
||||
dpcpu = dpcpu_off[i];
|
||||
if (dpcpu == 0)
|
||||
continue;
|
||||
count += *(int *)(dpcpu + (uintptr_t)arg1);
|
||||
}
|
||||
return (SYSCTL_OUT(req, &count, sizeof(count)));
|
||||
}
|
||||
|
||||
#ifdef DDB
|
||||
DB_SHOW_COMMAND(dpcpu_off, db_show_dpcpu_off)
|
||||
{
|
||||
int id;
|
||||
|
||||
for (id = 0; id <= mp_maxid; id++) {
|
||||
if (CPU_ABSENT(id))
|
||||
continue;
|
||||
db_printf("dpcpu_off[%2d] = 0x%jx (+ DPCPU_START = %p)\n",
|
||||
id, (uintmax_t)dpcpu_off[id],
|
||||
(void *)(uintptr_t)(dpcpu_off[id] + DPCPU_START));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_pcpu(struct pcpu *pc)
|
||||
{
|
||||
struct thread *td;
|
||||
|
||||
db_printf("cpuid = %d\n", pc->pc_cpuid);
|
||||
db_printf("dynamic pcpu = %p\n", (void *)pc->pc_dynamic);
|
||||
db_printf("curthread = ");
|
||||
td = pc->pc_curthread;
|
||||
if (td != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", td, td->td_proc->p_pid,
|
||||
td->td_name);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_printf("curpcb = %p\n", pc->pc_curpcb);
|
||||
db_printf("fpcurthread = ");
|
||||
td = pc->pc_fpcurthread;
|
||||
if (td != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", td, td->td_proc->p_pid,
|
||||
td->td_name);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_printf("idlethread = ");
|
||||
td = pc->pc_idlethread;
|
||||
if (td != NULL)
|
||||
db_printf("%p: tid %d \"%s\"\n", td, td->td_tid, td->td_name);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_show_mdpcpu(pc);
|
||||
|
||||
#ifdef VIMAGE
|
||||
db_printf("curvnet = %p\n", pc->pc_curthread->td_vnet);
|
||||
#endif
|
||||
|
||||
#ifdef WITNESS
|
||||
db_printf("spin locks held:\n");
|
||||
witness_list_locks(&pc->pc_spinlocks, db_printf);
|
||||
#endif
|
||||
}
|
||||
|
||||
DB_SHOW_COMMAND(pcpu, db_show_pcpu)
|
||||
{
|
||||
struct pcpu *pc;
|
||||
int id;
|
||||
|
||||
if (have_addr)
|
||||
id = ((addr >> 4) % 16) * 10 + (addr % 16);
|
||||
else
|
||||
id = PCPU_GET(cpuid);
|
||||
pc = pcpu_find(id);
|
||||
if (pc == NULL) {
|
||||
db_printf("CPU %d not found\n", id);
|
||||
return;
|
||||
}
|
||||
show_pcpu(pc);
|
||||
}
|
||||
|
||||
DB_SHOW_ALL_COMMAND(pcpu, db_show_cpu_all)
|
||||
{
|
||||
struct pcpu *pc;
|
||||
int id;
|
||||
|
||||
db_printf("Current CPU: %d\n\n", PCPU_GET(cpuid));
|
||||
for (id = 0; id <= mp_maxid; id++) {
|
||||
pc = pcpu_find(id);
|
||||
if (pc != NULL) {
|
||||
show_pcpu(pc);
|
||||
db_printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
DB_SHOW_ALIAS(allpcpu, db_show_cpu_all);
|
||||
#endif
|
@ -1045,8 +1045,8 @@ netisr_start_swi(u_int cpuid, struct pcpu *pc)
|
||||
SWI_NET, INTR_MPSAFE, &nwsp->nws_swi_cookie);
|
||||
if (error)
|
||||
panic("%s: swi_add %d", __func__, error);
|
||||
pc->pc_netisr = nwsp->nws_intr_event;
|
||||
#ifndef __rtems__
|
||||
pc->pc_netisr = nwsp->nws_intr_event;
|
||||
if (netisr_bindthreads) {
|
||||
error = intr_event_bind(nwsp->nws_intr_event, cpuid);
|
||||
if (error != 0)
|
||||
@ -1101,10 +1101,15 @@ netisr_init(void *arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __rtems__
|
||||
netisr_start_swi(curcpu, pcpu_find(curcpu));
|
||||
#else /* __rtems__ */
|
||||
netisr_start_swi(0, NULL);
|
||||
#endif /* __rtems__ */
|
||||
}
|
||||
SYSINIT(netisr_init, SI_SUB_SOFTINTR, SI_ORDER_FIRST, netisr_init, NULL);
|
||||
|
||||
#ifndef __rtems__
|
||||
/*
|
||||
* Start worker threads for additional CPUs. No attempt to gracefully handle
|
||||
* work reassignment, we don't yet support dynamic reconfiguration.
|
||||
@ -1127,6 +1132,7 @@ netisr_start(void *arg)
|
||||
}
|
||||
}
|
||||
SYSINIT(netisr_start, SI_SUB_SMP, SI_ORDER_MIDDLE, netisr_start, NULL);
|
||||
#endif /* __rtems__ */
|
||||
|
||||
#ifdef DDB
|
||||
DB_SHOW_COMMAND(netisr, db_show_netisr)
|
||||
|
@ -56,19 +56,6 @@ int hz;
|
||||
int tick;
|
||||
int maxusers; /* base tunable */
|
||||
|
||||
|
||||
static struct pcpu FIXME_pcpu[MAXCPU];
|
||||
|
||||
/*
|
||||
* Initialize per cpu data structures. Based off
|
||||
* of the freeBSD mips method mips_pcpu0_init()
|
||||
*/
|
||||
static void
|
||||
pcpu0_init()
|
||||
{
|
||||
/* Initialize pcpu info of cpu-zero */
|
||||
pcpu_init((char *)&FIXME_pcpu[0], 0, sizeof(struct pcpu));
|
||||
}
|
||||
rtems_id rtems_init_task_id;
|
||||
|
||||
rtems_status_code
|
||||
@ -91,7 +78,6 @@ rtems_bsd_initialize(void)
|
||||
}
|
||||
|
||||
mutex_init();
|
||||
pcpu0_init();
|
||||
mi_startup();
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user