From 5bc3a65e406b90cd9e2a47b79117e453bdb56413 Mon Sep 17 00:00:00 2001 From: jeff Date: Tue, 23 Jun 2009 22:42:39 +0000 Subject: Implement a facility for dynamic per-cpu variables. - Modules and kernel code alike may use DPCPU_DEFINE(), DPCPU_GET(), DPCPU_SET(), etc. akin to the statically defined PCPU_*. Requires only one extra instruction more than PCPU_* and is virtually the same as __thread for builtin and much faster for shared objects. DPCPU variables can be initialized when defined. - Modules are supported by relocating the module's per-cpu linker set over space reserved in the kernel. Modules may fail to load if there is insufficient space available. - Track space available for modules with a one-off extent allocator. Free may block for memory to allocate space for an extent. Reviewed by: jhb, rwatson, kan, sam, grehan, marius, marcel, stas --- sys/ia64/ia64/elf_machdep.c | 2 +- sys/ia64/ia64/machdep.c | 32 +++++++++++++++++--------------- sys/ia64/ia64/mp_machdep.c | 3 +++ 3 files changed, 21 insertions(+), 16 deletions(-) (limited to 'sys/ia64') diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c index a100671..31765cc 100644 --- a/sys/ia64/ia64/elf_machdep.c +++ b/sys/ia64/ia64/elf_machdep.c @@ -211,7 +211,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, if (local) { if (rtype == R_IA_64_REL64LSB) - *where = relocbase + addend; + *where = elf_relocaddr(lf, relocbase + addend); return (0); } diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index dda1a08..b1e7298 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -647,6 +647,21 @@ ia64_init(void) bootverbose = 1; /* + * Find the beginning and end of the kernel. + */ + kernstart = trunc_page(kernel_text); +#ifdef DDB + ksym_start = bootinfo.bi_symtab; + ksym_end = bootinfo.bi_esymtab; + kernend = (vm_offset_t)round_page(ksym_end); +#else + kernend = (vm_offset_t)round_page(_end); +#endif + /* But if the bootstrap tells us otherwise, believe it! */ + if (bootinfo.bi_kernend) + kernend = round_page(bootinfo.bi_kernend); + + /* * Setup the PCPU data for the bootstrap processor. It is needed * by printf(). Also, since printf() has critical sections, we * need to initialize at least pc_curthread. @@ -654,6 +669,8 @@ ia64_init(void) pcpup = &pcpu0; ia64_set_k4((u_int64_t)pcpup); pcpu_init(pcpup, 0, sizeof(pcpu0)); + dpcpu_init((void *)kernend, 0); + kernend += DPCPU_SIZE; PCPU_SET(curthread, &thread0); /* @@ -682,21 +699,6 @@ ia64_init(void) ia64_sal_init(); calculate_frequencies(); - /* - * Find the beginning and end of the kernel. - */ - kernstart = trunc_page(kernel_text); -#ifdef DDB - ksym_start = bootinfo.bi_symtab; - ksym_end = bootinfo.bi_esymtab; - kernend = (vm_offset_t)round_page(ksym_end); -#else - kernend = (vm_offset_t)round_page(_end); -#endif - - /* But if the bootstrap tells us otherwise, believe it! */ - if (bootinfo.bi_kernend) - kernend = round_page(bootinfo.bi_kernend); if (metadata_missing) printf("WARNING: loader(8) metadata is missing!\n"); diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index 6dba43a..e94acad 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -207,6 +207,7 @@ cpu_mp_add(u_int acpiid, u_int apicid, u_int apiceid) { struct pcpu *pc; u_int64_t lid; + void *dpcpu; /* Ignore any processor numbers outside our range */ if (acpiid > mp_maxid) @@ -224,7 +225,9 @@ cpu_mp_add(u_int acpiid, u_int apicid, u_int apiceid) if (acpiid != 0) { pc = (struct pcpu *)malloc(sizeof(*pc), M_SMP, M_WAITOK); + dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE); pcpu_init(pc, acpiid, sizeof(*pc)); + dpcpu_init(dpcpu, acpiid); } else pc = pcpup; -- cgit v1.1