Пример #1
0
/**
 * irq_matrix_reserve_managed - Reserve a managed interrupt in a CPU map
 * @m:		Matrix pointer
 * @msk:	On which CPUs the bits should be reserved.
 *
 * Can be called for offline CPUs. Note, this will only reserve one bit
 * on all CPUs in @msk, but it's not guaranteed that the bits are at the
 * same offset on all CPUs
 */
int irq_matrix_reserve_managed(struct irq_matrix *m, const struct cpumask *msk)
{
	unsigned int cpu, failed_cpu;

	for_each_cpu(cpu, msk) {
		struct cpumap *cm = per_cpu_ptr(m->maps, cpu);
		unsigned int bit;

		bit = matrix_alloc_area(m, cm, 1, true);
		if (bit >= m->alloc_end)
			goto cleanup;
		cm->managed++;
		if (cm->online) {
			cm->available--;
			m->global_available--;
		}
		trace_irq_matrix_reserve_managed(bit, cpu, m, cm);
	}
	return 0;
cleanup:
	failed_cpu = cpu;
	for_each_cpu(cpu, msk) {
		if (cpu == failed_cpu)
			break;
		irq_matrix_remove_managed(m, cpumask_of(cpu));
	}
	return -ENOSPC;
}
Пример #2
0
/**
 * irq_matrix_alloc - Allocate a regular interrupt in a CPU map
 * @m:		Matrix pointer
 * @msk:	Which CPUs to search in
 * @reserved:	Allocate previously reserved interrupts
 * @mapped_cpu: Pointer to store the CPU for which the irq was allocated
 */
int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk,
		     bool reserved, unsigned int *mapped_cpu)
{
	unsigned int cpu;

	for_each_cpu(cpu, msk) {
		struct cpumap *cm = per_cpu_ptr(m->maps, cpu);
		unsigned int bit;

		if (!cm->online)
			continue;

		bit = matrix_alloc_area(m, cm, 1, false);
		if (bit < m->alloc_end) {
			cm->allocated++;
			cm->available--;
			m->total_allocated++;
			m->global_available--;
			if (reserved)
				m->global_reserved--;
			*mapped_cpu = cpu;
			trace_irq_matrix_alloc(bit, cpu, m, cm);
			return bit;
		}
	}
	return -ENOSPC;
}