Skip to content

Commit

Permalink
kernel - Reduce BSS size to fix loader initrd problem
Browse files Browse the repository at this point in the history
* kernel + modules + initrd.img (unpacked) exceeded the 63MB the loader has
  available for load-time data.

* Top hogs are mainly in BSS.  Make intr_info_ary and pcpu_sysctl
  kmalloc after boot instead of BSS as a temporary fix.

    335872  ifnet_threads
    335872  netisr_cpu
    339968  dummy_pcpu
    344064  bsd4_pcpu
    344064  stoppcbs
    346112  softclock_pcpu_ary
    538624  cpu_topology_nodes
    755712  dfly_pcpu
    786432  icu_irqmaps
    958464  map_entry_init
    1048576 idt_arr
    1064960 pcpu_sysctl		<---- now kmallocd
    1179648 ioapic_irqmaps	<---- (used too early, cannot be kmallocd)
    5242880 intr_info_ary	<---- now kmallocd

* Should fix loader issues when trying to use initrd.img[.gz] for now.

Reported-by: Valheru
  • Loading branch information
Charlie Root committed Apr 23, 2016
1 parent d90e4fd commit d8f4ebf
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 18 deletions.
42 changes: 26 additions & 16 deletions sys/kern/kern_intr.c
Expand Up @@ -74,11 +74,18 @@ struct intr_info {
int i_intr;
};

static struct intr_info intr_info_ary[MAXCPU][MAX_INTS];
struct intr_info_block {
struct intr_info ary[MAXCPU][MAX_INTS];
};

static struct intr_info_block *intr_block;
static struct intr_info *swi_info_ary[MAX_SOFTINTS];

static int max_installed_hard_intr[MAXCPU];

MALLOC_DEFINE(M_INTRMNG, "intrmng", "interrupt management");


#define EMERGENCY_INTR_POLLING_FREQ_MAX 20000

/*
Expand Down Expand Up @@ -245,7 +252,7 @@ register_int(int intr, inthand2_t *handler, void *arg, const char *name,
panic("register_int: bad intr %d", intr);
if (name == NULL)
name = "???";
info = &intr_info_ary[cpuid][intr];
info = &intr_block->ary[cpuid][intr];

/*
* Construct an interrupt handler record
Expand Down Expand Up @@ -375,7 +382,7 @@ unregister_int(void *id, int cpuid)
if (intr < 0 || intr >= MAX_INTS)
panic("register_int: bad intr %d", intr);

info = &intr_info_ary[cpuid][intr];
info = &intr_block->ary[cpuid][intr];

int_moveto_destcpu(&orig_cpuid, cpuid);

Expand Down Expand Up @@ -441,7 +448,7 @@ get_interrupt_counter(int intr, int cpuid)

if (intr < 0 || intr >= MAX_INTS)
panic("register_int: bad intr %d", intr);
info = &intr_info_ary[cpuid][intr];
info = &intr_block->ary[cpuid][intr];
return(info->i_count);
}

Expand All @@ -455,7 +462,7 @@ register_randintr(int intr)
panic("register_randintr: bad intr %d", intr);

for (cpuid = 0; cpuid < ncpus; ++cpuid) {
info = &intr_info_ary[cpuid][intr];
info = &intr_block->ary[cpuid][intr];
info->i_random.sc_intr = intr;
info->i_random.sc_enabled = 1;
}
Expand All @@ -471,7 +478,7 @@ unregister_randintr(int intr)
panic("register_swi: bad intr %d", intr);

for (cpuid = 0; cpuid < ncpus; ++cpuid) {
info = &intr_info_ary[cpuid][intr];
info = &intr_block->ary[cpuid][intr];
info->i_random.sc_enabled = -1;
}
}
Expand All @@ -488,7 +495,7 @@ next_registered_randintr(int intr)
int cpuid;

for (cpuid = 0; cpuid < ncpus; ++cpuid) {
info = &intr_info_ary[cpuid][intr];
info = &intr_block->ary[cpuid][intr];
if (info->i_random.sc_enabled > 0)
return intr;
}
Expand Down Expand Up @@ -562,7 +569,7 @@ void
sched_ithd_hard(int intr)
{
KKASSERT(intr >= 0 && intr < MAX_HARDINTS);
sched_ithd_intern(&intr_info_ary[mycpuid][intr]);
sched_ithd_intern(&intr_block->ary[mycpuid][intr]);
}

#ifdef _KERNEL_VIRTUAL
Expand All @@ -571,7 +578,7 @@ void
sched_ithd_hard_virtual(int intr)
{
KKASSERT(intr >= 0 && intr < MAX_HARDINTS);
sched_ithd_intern(&intr_info_ary[0][intr]);
sched_ithd_intern(&intr_block->ary[0][intr]);
}

void *
Expand Down Expand Up @@ -616,7 +623,7 @@ ithread_livelock_wakeup(systimer_t st, int in_ipi __unused,
{
struct intr_info *info;

info = &intr_info_ary[mycpuid][(int)(intptr_t)st->data];
info = &intr_block->ary[mycpuid][(int)(intptr_t)st->data];
if (info->i_state != ISTATE_NOTHREAD)
lwkt_schedule(info->i_thread);
}
Expand Down Expand Up @@ -674,7 +681,7 @@ ithread_fast_handler(struct intrframe *frame)
/* We must be in critical section. */
KKASSERT(td->td_critcount);

info = &intr_info_ary[mycpuid][intr];
info = &intr_block->ary[mycpuid][intr];

/*
* If we are not processing any FAST interrupts, just schedule the thing.
Expand Down Expand Up @@ -787,7 +794,7 @@ ithread_handler(void *arg)

ill_count = 0;
intr = (int)(intptr_t)arg;
info = &intr_info_ary[cpuid][intr];
info = &intr_block->ary[cpuid][intr];
list = &info->i_reclist;

/*
Expand Down Expand Up @@ -978,7 +985,7 @@ ithread_emergency(void *arg __unused)

for (;;) {
for (intr = 0; intr < max_installed_hard_intr[cpuid]; ++intr) {
info = &intr_info_ary[cpuid][intr];
info = &intr_block->ary[cpuid][intr];
for (rec = info->i_reclist; rec; rec = nrec) {
/* rec may be invalid after call */
nrec = rec->next;
Expand Down Expand Up @@ -1034,7 +1041,7 @@ sysctl_intrnames(SYSCTL_HANDLER_ARGS)

for (cpuid = 0; cpuid < ncpus; ++cpuid) {
for (intr = 0; error == 0 && intr < MAX_INTS; ++intr) {
info = &intr_info_ary[cpuid][intr];
info = &intr_block->ary[cpuid][intr];

len = 0;
buf[0] = 0;
Expand Down Expand Up @@ -1065,7 +1072,7 @@ sysctl_intrcnt_all(SYSCTL_HANDLER_ARGS)

for (cpuid = 0; cpuid < ncpus; ++cpuid) {
for (intr = 0; intr < MAX_INTS; ++intr) {
info = &intr_info_ary[cpuid][intr];
info = &intr_block->ary[cpuid][intr];

error = SYSCTL_OUT(req, &info->i_count, sizeof(info->i_count));
if (error)
Expand Down Expand Up @@ -1107,11 +1114,14 @@ intr_init(void *dummy __unused)

kprintf("Initialize MI interrupts\n");

intr_block = kmalloc(sizeof(*intr_block), M_INTRMNG,
M_INTWAIT | M_ZERO);

for (cpuid = 0; cpuid < ncpus; ++cpuid) {
int intr;

for (intr = 0; intr < MAX_INTS; ++intr) {
struct intr_info *info = &intr_info_ary[cpuid][intr];
struct intr_info *info = &intr_block->ary[cpuid][intr];

info->i_cpuid = cpuid;
info->i_intr = intr;
Expand Down
9 changes: 7 additions & 2 deletions sys/kern/subr_cpu_topology.c
Expand Up @@ -64,12 +64,15 @@ static cpu_node_t *cpu_root_node; /* Root node pointer */
static struct sysctl_ctx_list cpu_topology_sysctl_ctx;
static struct sysctl_oid *cpu_topology_sysctl_tree;
static char cpu_topology_members[8*MAXCPU];
static per_cpu_sysctl_info_t pcpu_sysctl[MAXCPU];
static per_cpu_sysctl_info_t *pcpu_sysctl;
static void sbuf_print_cpuset(struct sbuf *sb, cpumask_t *mask);

int cpu_topology_levels_number = 1;
cpu_node_t *root_cpu_node;

MALLOC_DEFINE(M_PCPUSYS, "pcpusys", "pcpu sysctl topology");


/* Get the next valid apicid starting
* from current apicid (curr_apicid
*/
Expand Down Expand Up @@ -534,8 +537,10 @@ init_pcpu_topology_sysctl(void)
cpumask_t mask;
struct sbuf sb;

for (i = 0; i < ncpus; i++) {
pcpu_sysctl = kmalloc(sizeof(*pcpu_sysctl) * MAXCPU, M_PCPUSYS,
M_INTWAIT | M_ZERO);

for (i = 0; i < ncpus; i++) {
sbuf_new(&sb, pcpu_sysctl[i].cpu_name,
sizeof(pcpu_sysctl[i].cpu_name), SBUF_FIXEDLEN);
sbuf_printf(&sb,"cpu%d", i);
Expand Down
3 changes: 3 additions & 0 deletions sys/platform/pc64/apic/ioapic_abi.c
Expand Up @@ -457,6 +457,9 @@ static inthand_t *ioapic_intr[IOAPIC_HWI_VECTORS] = {

#define IOAPIC_HWI_SYSCALL (IDT_OFFSET_SYSCALL - IDT_OFFSET)

/*
* NOTE: Initialized before VM so cannot use kmalloc() for this array.
*/
static struct ioapic_irqmap {
int im_type; /* IOAPIC_IMT_ */
enum intr_trigger im_trig;
Expand Down

0 comments on commit d8f4ebf

Please sign in to comment.