Lines Matching +full:reserved +full:- +full:cpu +full:- +full:vectors

1 // SPDX-License-Identifier: GPL-2.0-only
30 unsigned int cpu; member
78 info->mask = mask; in init_irq_alloc_info()
94 while (irqd->parent_data) in apic_chip_data()
95 irqd = irqd->parent_data; in apic_chip_data()
97 return irqd->chip_data; in apic_chip_data()
104 return apicd ? &apicd->hw_irq_cfg : NULL; in irqd_cfg()
119 INIT_HLIST_NODE(&apicd->clist); in alloc_apic_chip_data()
129 unsigned int cpu) in apic_update_irq_cfg() argument
135 apicd->hw_irq_cfg.vector = vector; in apic_update_irq_cfg()
136 apicd->hw_irq_cfg.dest_apicid = apic->calc_dest_apicid(cpu); in apic_update_irq_cfg()
137 irq_data_update_effective_affinity(irqd, cpumask_of(cpu)); in apic_update_irq_cfg()
138 trace_vector_config(irqd->irq, vector, cpu, in apic_update_irq_cfg()
139 apicd->hw_irq_cfg.dest_apicid); in apic_update_irq_cfg()
151 trace_vector_update(irqd->irq, newvec, newcpu, apicd->vector, in apic_update_vector()
152 apicd->cpu); in apic_update_vector()
160 apicd->prev_vector = 0; in apic_update_vector()
161 if (!apicd->vector || apicd->vector == MANAGED_IRQ_SHUTDOWN_VECTOR) in apic_update_vector()
164 * If the target CPU of the previous vector is online, then mark in apic_update_vector()
166 * first interrupt on the new vector arrives. If the target CPU is in apic_update_vector()
171 if (cpu_online(apicd->cpu)) { in apic_update_vector()
172 apicd->move_in_progress = true; in apic_update_vector()
173 apicd->prev_vector = apicd->vector; in apic_update_vector()
174 apicd->prev_cpu = apicd->cpu; in apic_update_vector()
175 WARN_ON_ONCE(apicd->cpu == newcpu); in apic_update_vector()
177 irq_matrix_free(vector_matrix, apicd->cpu, apicd->vector, in apic_update_vector()
182 apicd->vector = newvec; in apic_update_vector()
183 apicd->cpu = newcpu; in apic_update_vector()
190 unsigned int cpu = cpumask_first(cpu_online_mask); in vector_assign_managed_shutdown() local
192 apic_update_irq_cfg(irqd, MANAGED_IRQ_SHUTDOWN_VECTOR, cpu); in vector_assign_managed_shutdown()
203 apicd->is_managed = true; in reserve_managed_vector()
206 trace_vector_reserve_managed(irqd->irq, ret); in reserve_managed_vector()
215 apicd->can_reserve = true; in reserve_irq_vector_locked()
216 apicd->has_reserved = true; in reserve_irq_vector_locked()
218 trace_vector_reserve(irqd->irq, 0); in reserve_irq_vector_locked()
236 bool resvd = apicd->has_reserved; in assign_vector_locked()
237 unsigned int cpu = apicd->cpu; in assign_vector_locked() local
238 int vector = apicd->vector; in assign_vector_locked()
243 * If the current target CPU is online and in the new requested in assign_vector_locked()
245 * one CPU to another. in assign_vector_locked()
247 if (vector && cpu_online(cpu) && cpumask_test_cpu(cpu, dest)) in assign_vector_locked()
253 * leave a stale vector on some CPU around or in case of a pending in assign_vector_locked()
256 if (apicd->move_in_progress || !hlist_unhashed(&apicd->clist)) in assign_vector_locked()
257 return -EBUSY; in assign_vector_locked()
259 vector = irq_matrix_alloc(vector_matrix, dest, resvd, &cpu); in assign_vector_locked()
260 trace_vector_alloc(irqd->irq, vector, resvd, vector); in assign_vector_locked()
263 apic_update_vector(irqd, vector, cpu); in assign_vector_locked()
264 apic_update_irq_cfg(irqd, vector, cpu); in assign_vector_locked()
283 /* Get the affinity mask - either irq_default_affinity or (user) set */ in assign_irq_vector_any_locked()
314 if (info->mask) in assign_irq_vector_policy()
315 return assign_irq_vector(irqd, info->mask); in assign_irq_vector_policy()
328 int vector, cpu; in assign_managed_vector() local
333 if (apicd->vector && cpumask_test_cpu(apicd->cpu, vector_searchmask)) in assign_managed_vector()
336 &cpu); in assign_managed_vector()
337 trace_vector_alloc_managed(irqd->irq, vector, vector); in assign_managed_vector()
340 apic_update_vector(irqd, vector, cpu); in assign_managed_vector()
341 apic_update_irq_cfg(irqd, vector, cpu); in assign_managed_vector()
349 unsigned int vector = apicd->vector; in clear_irq_vector()
356 trace_vector_clear(irqd->irq, vector, apicd->cpu, apicd->prev_vector, in clear_irq_vector()
357 apicd->prev_cpu); in clear_irq_vector()
359 per_cpu(vector_irq, apicd->cpu)[vector] = VECTOR_SHUTDOWN; in clear_irq_vector()
360 irq_matrix_free(vector_matrix, apicd->cpu, vector, managed); in clear_irq_vector()
361 apicd->vector = 0; in clear_irq_vector()
364 vector = apicd->prev_vector; in clear_irq_vector()
368 per_cpu(vector_irq, apicd->prev_cpu)[vector] = VECTOR_SHUTDOWN; in clear_irq_vector()
369 irq_matrix_free(vector_matrix, apicd->prev_cpu, vector, managed); in clear_irq_vector()
370 apicd->prev_vector = 0; in clear_irq_vector()
371 apicd->move_in_progress = 0; in clear_irq_vector()
372 hlist_del_init(&apicd->clist); in clear_irq_vector()
380 trace_vector_deactivate(irqd->irq, apicd->is_managed, in x86_vector_deactivate()
381 apicd->can_reserve, false); in x86_vector_deactivate()
384 if (!apicd->is_managed && !apicd->can_reserve) in x86_vector_deactivate()
387 if (apicd->has_reserved) in x86_vector_deactivate()
392 if (apicd->can_reserve) in x86_vector_deactivate()
406 apicd->has_reserved = false; in activate_reserved()
415 apicd->can_reserve = false; in activate_reserved()
425 irqd->irq); in activate_reserved()
439 pr_err("Managed startup for irq %u, but no CPU\n", irqd->irq); in activate_managed()
440 return -EINVAL; in activate_managed()
450 irqd->irq); in activate_managed()
462 trace_vector_activate(irqd->irq, apicd->is_managed, in x86_vector_activate()
463 apicd->can_reserve, reserve); in x86_vector_activate()
466 if (!apicd->can_reserve && !apicd->is_managed) in x86_vector_activate()
470 else if (apicd->is_managed) in x86_vector_activate()
472 else if (apicd->has_reserved) in x86_vector_activate()
483 trace_vector_teardown(irqd->irq, apicd->is_managed, in vector_free_reserved_and_managed()
484 apicd->has_reserved); in vector_free_reserved_and_managed()
486 if (apicd->has_reserved) in vector_free_reserved_and_managed()
488 if (apicd->is_managed) in vector_free_reserved_and_managed()
502 if (irqd && irqd->chip_data) { in x86_vector_free_irqs()
506 apicd = irqd->chip_data; in x86_vector_free_irqs()
520 apicd->vector = ISA_IRQ_VECTOR(virq); in vector_configure_legacy()
521 apicd->cpu = 0; in vector_configure_legacy()
530 apic_update_irq_cfg(irqd, apicd->vector, apicd->cpu); in vector_configure_legacy()
533 apicd->can_reserve = true; in vector_configure_legacy()
551 return -ENXIO; in x86_vector_alloc_irqs()
557 if (WARN_ON_ONCE(info->flags & X86_IRQ_ALLOC_LEGACY && in x86_vector_alloc_irqs()
559 return -EINVAL; in x86_vector_alloc_irqs()
565 WARN_ON_ONCE(irqd->chip_data); in x86_vector_alloc_irqs()
568 err = -ENOMEM; in x86_vector_alloc_irqs()
572 apicd->irq = virq + i; in x86_vector_alloc_irqs()
573 irqd->chip = &lapic_controller; in x86_vector_alloc_irqs()
574 irqd->chip_data = apicd; in x86_vector_alloc_irqs()
575 irqd->hwirq = virq + i; in x86_vector_alloc_irqs()
588 * Legacy vectors are already assigned when the IOAPIC in x86_vector_alloc_irqs()
594 if (info->flags & X86_IRQ_ALLOC_LEGACY) { in x86_vector_alloc_irqs()
602 irqd->chip_data = NULL; in x86_vector_alloc_irqs()
628 irq = irqd->irq; in x86_vector_debug_show()
635 if (!irqd->chip_data) { in x86_vector_debug_show()
641 memcpy(&apicd, irqd->chip_data, sizeof(apicd)); in x86_vector_debug_show()
645 seq_printf(m, "%*sTarget: %5u\n", ind, "", apicd.cpu); in x86_vector_debug_show()
660 if (fwspec->param_count != 1) in x86_fwspec_is_ioapic()
663 if (is_fwnode_irqchip(fwspec->fwnode)) { in x86_fwspec_is_ioapic()
664 const char *fwname = fwnode_get_name(fwspec->fwnode); in x86_fwspec_is_ioapic()
665 return fwname && !strncmp(fwname, "IO-APIC-", 8) && in x86_fwspec_is_ioapic()
666 simple_strtol(fwname+8, NULL, 10) == fwspec->param[0]; in x86_fwspec_is_ioapic()
668 return to_of_node(fwspec->fwnode) && in x86_fwspec_is_ioapic()
669 of_device_is_compatible(to_of_node(fwspec->fwnode), in x86_fwspec_is_ioapic()
670 "intel,ce4100-ioapic"); in x86_fwspec_is_ioapic()
675 if (fwspec->param_count != 1) in x86_fwspec_is_hpet()
678 if (is_fwnode_irqchip(fwspec->fwnode)) { in x86_fwspec_is_hpet()
679 const char *fwname = fwnode_get_name(fwspec->fwnode); in x86_fwspec_is_hpet()
680 return fwname && !strncmp(fwname, "HPET-MSI-", 9) && in x86_fwspec_is_hpet()
681 simple_strtol(fwname+9, NULL, 10) == fwspec->param[0]; in x86_fwspec_is_hpet()
735 return legacy_pic->probe(); in arch_probe_nr_irqs()
742 * and movable in the cpu hotplug check and it prevents managed in lapic_assign_legacy_vector()
759 * vectors. PIC_CASCADE_IRQ has already been marked in in lapic_update_legacy_vectors()
778 /* System vectors are reserved, online it */ in lapic_assign_system_vectors()
821 int isairq = vector - ISA_IRQ_VECTOR(0); in __setup_vector_irq()
832 /* Online the local APIC infrastructure and initialize the vectors */
839 /* Online the vector matrix array for this CPU */ in lapic_online()
846 * they can be distributed to any online CPU in hardware. The in lapic_online()
847 * kernel has no influence on that. So all active legacy vectors in lapic_online()
867 WARN_ON_ONCE(try_to_del_timer_sync(&cl->timer) < 0); in lapic_offline()
868 WARN_ON_ONCE(!hlist_empty(&cl->head)); in lapic_offline()
879 return -EIO; in apic_set_affinity()
901 __apic_send_IPI(apicd->cpu, apicd->vector); in apic_retrigger_irq()
937 unsigned int vector = apicd->prev_vector; in free_moved_vector()
938 unsigned int cpu = apicd->prev_cpu; in free_moved_vector() local
939 bool managed = apicd->is_managed; in free_moved_vector()
943 * from an online CPU, but CPU isolation 'managed_irq' in free_moved_vector()
947 * 2) Migration away from an isolated CPU can happen when in free_moved_vector()
948 * a non-isolated CPU which is in the calculated in free_moved_vector()
951 trace_vector_free_moved(apicd->irq, cpu, vector, managed); in free_moved_vector()
952 irq_matrix_free(vector_matrix, cpu, vector, managed); in free_moved_vector()
953 per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED; in free_moved_vector()
954 hlist_del_init(&apicd->clist); in free_moved_vector()
955 apicd->prev_vector = 0; in free_moved_vector()
956 apicd->move_in_progress = 0; in free_moved_vector()
967 hlist_for_each_entry_safe(apicd, tmp, &cl->head, clist) { in __vector_cleanup()
968 unsigned int vector = apicd->prev_vector; in __vector_cleanup()
975 * on the list and schedule the timer again to give the CPU in __vector_cleanup()
983 pr_warn_once("Moved interrupt pending in old target APIC %u\n", apicd->irq); in __vector_cleanup()
995 mod_timer(&cl->timer, jiffies + 1); in __vector_cleanup()
1002 /* Prevent vectors vanishing under us */ in vector_cleanup_callback()
1010 unsigned int cpu = apicd->prev_cpu; in __vector_schedule_cleanup() local
1013 apicd->move_in_progress = 0; in __vector_schedule_cleanup()
1014 if (cpu_online(cpu)) { in __vector_schedule_cleanup()
1015 struct vector_cleanup *cl = per_cpu_ptr(&vector_cleanup, cpu); in __vector_schedule_cleanup()
1017 hlist_add_head(&apicd->clist, &cl->head); in __vector_schedule_cleanup()
1026 * or the other CPU executes the callback, which again in __vector_schedule_cleanup()
1033 if (!timer_pending(&cl->timer)) { in __vector_schedule_cleanup()
1034 cl->timer.expires = jiffies + 1; in __vector_schedule_cleanup()
1035 add_timer_on(&cl->timer, cpu); in __vector_schedule_cleanup()
1038 pr_warn("IRQ %u schedule cleanup for offline CPU %u\n", apicd->irq, cpu); in __vector_schedule_cleanup()
1049 if (apicd->move_in_progress) in vector_schedule_cleanup()
1058 if (likely(!apicd->move_in_progress)) in irq_complete_move()
1062 * If the interrupt arrived on the new target CPU, cleanup the in irq_complete_move()
1063 * vector on the old target CPU. A vector check is not required in irq_complete_move()
1065 * on the same CPU. in irq_complete_move()
1067 if (apicd->cpu == smp_processor_id()) in irq_complete_move()
1072 * Called from fixup_irqs() with @desc->lock held and interrupts disabled.
1076 unsigned int cpu = smp_processor_id(); in irq_force_complete_move() local
1102 * nor previously on the outgoing CPU no action required. in irq_force_complete_move()
1104 vector = apicd->prev_vector; in irq_force_complete_move()
1105 if (!vector || (apicd->cpu != cpu && apicd->prev_cpu != cpu)) in irq_force_complete_move()
1111 * -EBUSY. This can leave the interrupt in a stale state. in irq_force_complete_move()
1123 if (apicd->move_in_progress) { in irq_force_complete_move()
1127 * set_ioapic(new_vector) <-- Interrupt is raised before update in irq_force_complete_move()
1131 * So if the target cpu cannot handle that interrupt before in irq_force_complete_move()
1135 * But in case of cpu hotplug this should be a non issue in irq_force_complete_move()
1138 * interrupt can be blocked on the target cpu because all cpus in irq_force_complete_move()
1144 * beyond the point where the target cpu disables interrupts in irq_force_complete_move()
1157 irqd->irq, vector); in irq_force_complete_move()
1167 * prevent that the actual interrupt move will run out of vectors.
1171 unsigned int rsvd, avl, tomove, cpu = smp_processor_id(); in lapic_can_unplug_cpu() local
1178 pr_warn("CPU %u has %u vectors, %u available. Cannot disable CPU\n", in lapic_can_unplug_cpu()
1179 cpu, tomove, avl); in lapic_can_unplug_cpu()
1180 ret = -ENOSPC; in lapic_can_unplug_cpu()
1185 pr_warn("Reserved vectors %u > available %u. IRQ request may fail\n", in lapic_can_unplug_cpu()
1212 pr_debug("printing local APIC contents on CPU#%d/%d:\n", in print_local_APIC()
1316 int cpu; in print_local_APICs() local
1322 for_each_online_cpu(cpu) { in print_local_APICs()
1323 if (cpu >= maxcpu) in print_local_APICs()
1325 smp_call_function_single(cpu, print_local_APIC, NULL, 1); in print_local_APICs()
1365 int num = -1; in setup_show_lapic()