Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68e74568 authored by Rusty Russell's avatar Rusty Russell Committed by Ingo Molnar
Browse files

sched: convert struct cpupri_vec cpumask_var_t.



Impact: stack usage reduction, (future) size reduction for large NR_CPUS.

Dynamically allocating cpumasks (when CONFIG_CPUMASK_OFFSTACK) saves
space for small nr_cpu_ids but big CONFIG_NR_CPUS.

The fact cpupro_init is called both before and after the slab is
available makes for an ugly parameter unfortunately.

We also use cpumask_any_and to get rid of a temporary in cpupri_find.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 4212823f
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -6792,6 +6792,8 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent)

static void free_rootdomain(struct root_domain *rd)
{
	cpupri_cleanup(&rd->cpupri);

	free_cpumask_var(rd->rto_mask);
	free_cpumask_var(rd->online);
	free_cpumask_var(rd->span);
@@ -6834,7 +6836,7 @@ static int init_rootdomain(struct root_domain *rd, bool bootmem)
		alloc_bootmem_cpumask_var(&def_root_domain.span);
		alloc_bootmem_cpumask_var(&def_root_domain.online);
		alloc_bootmem_cpumask_var(&def_root_domain.rto_mask);
		cpupri_init(&rd->cpupri);
		cpupri_init(&rd->cpupri, true);
		return 0;
	}

@@ -6845,9 +6847,12 @@ static int init_rootdomain(struct root_domain *rd, bool bootmem)
	if (!alloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
		goto free_online;

	cpupri_init(&rd->cpupri);
	if (cpupri_init(&rd->cpupri, false) != 0)
		goto free_rto_mask;
	return 0;

free_rto_mask:
	free_cpumask_var(rd->rto_mask);
free_online:
	free_cpumask_var(rd->online);
free_span:
+28 −11
Original line number Diff line number Diff line
@@ -67,24 +67,21 @@ static int convert_prio(int prio)
 * Returns: (int)bool - CPUs were found
 */
int cpupri_find(struct cpupri *cp, struct task_struct *p,
		cpumask_t *lowest_mask)
		struct cpumask *lowest_mask)
{
	int                  idx      = 0;
	int                  task_pri = convert_prio(p->prio);

	for_each_cpupri_active(cp->pri_active, idx) {
		struct cpupri_vec *vec  = &cp->pri_to_cpu[idx];
		cpumask_t mask;

		if (idx >= task_pri)
			break;

		cpus_and(mask, p->cpus_allowed, vec->mask);

		if (cpus_empty(mask))
		if (cpumask_any_and(&p->cpus_allowed, vec->mask) >= nr_cpu_ids)
			continue;

		*lowest_mask = mask;
		cpumask_and(lowest_mask, &p->cpus_allowed, vec->mask);
		return 1;
	}

@@ -126,7 +123,7 @@ void cpupri_set(struct cpupri *cp, int cpu, int newpri)
		vec->count--;
		if (!vec->count)
			clear_bit(oldpri, cp->pri_active);
		cpu_clear(cpu, vec->mask);
		cpumask_clear_cpu(cpu, vec->mask);

		spin_unlock_irqrestore(&vec->lock, flags);
	}
@@ -136,7 +133,7 @@ void cpupri_set(struct cpupri *cp, int cpu, int newpri)

		spin_lock_irqsave(&vec->lock, flags);

		cpu_set(cpu, vec->mask);
		cpumask_set_cpu(cpu, vec->mask);
		vec->count++;
		if (vec->count == 1)
			set_bit(newpri, cp->pri_active);
@@ -150,10 +147,11 @@ void cpupri_set(struct cpupri *cp, int cpu, int newpri)
/**
 * cpupri_init - initialize the cpupri structure
 * @cp: The cpupri context
 * @bootmem: true if allocations need to use bootmem
 *
 * Returns: (void)
 * Returns: -ENOMEM if memory fails.
 */
void cpupri_init(struct cpupri *cp)
int cpupri_init(struct cpupri *cp, bool bootmem)
{
	int i;

@@ -164,11 +162,30 @@ void cpupri_init(struct cpupri *cp)

		spin_lock_init(&vec->lock);
		vec->count = 0;
		cpus_clear(vec->mask);
		if (bootmem)
			alloc_bootmem_cpumask_var(&vec->mask);
		else if (!alloc_cpumask_var(&vec->mask, GFP_KERNEL))
			goto cleanup;
	}

	for_each_possible_cpu(i)
		cp->cpu_to_pri[i] = CPUPRI_INVALID;
	return 0;

cleanup:
	for (i--; i >= 0; i--)
		free_cpumask_var(cp->pri_to_cpu[i].mask);
	return -ENOMEM;
}

/**
 * cpupri_cleanup - clean up the cpupri structure
 * @cp: The cpupri context
 */
void cpupri_cleanup(struct cpupri *cp)
{
	int i;

	for (i = 0; i < CPUPRI_NR_PRIORITIES; i++)
		free_cpumask_var(cp->pri_to_cpu[i].mask);
}
+3 −2
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
struct cpupri_vec {
	spinlock_t lock;
	int        count;
	cpumask_t  mask;
	cpumask_var_t mask;
};

struct cpupri {
@@ -27,7 +27,8 @@ struct cpupri {
int  cpupri_find(struct cpupri *cp,
		 struct task_struct *p, cpumask_t *lowest_mask);
void cpupri_set(struct cpupri *cp, int cpu, int pri);
void cpupri_init(struct cpupri *cp);
int cpupri_init(struct cpupri *cp, bool bootmem);
void cpupri_cleanup(struct cpupri *cp);
#else
#define cpupri_set(cp, cpu, pri) do { } while (0)
#define cpupri_init() do { } while (0)