Merge tag 'irq-core-2024-09-16' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner:
"Core:
- Remove a global lock in the affinity setting code
The lock protects a cpumask for intermediate results and the lock
causes a bottleneck on simultaneous start of multiple virtual
machines. Replace the lock and the static cpumask with a per CPU
cpumask which is nicely serialized by raw spinlock held when
executing this code.
- Provide support for giving a suffix to interrupt domain names.
That's required to support devices with subfunctions so that the
domain names are distinct even if they originate from the same
device node.
- The usual set of cleanups and enhancements all over the place
Drivers:
- Support for longarch AVEC interrupt chip
- Refurbishment of the Armada driver so it can be extended for new
variants.
- The usual set of cleanups and enhancements all over the place"
* tag 'irq-core-2024-09-16' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (73 commits)
genirq: Use cpumask_intersects()
genirq/cpuhotplug: Use cpumask_intersects()
irqchip/apple-aic: Only access system registers on SoCs which provide them
irqchip/apple-aic: Add a new "Global fast IPIs only" feature level
irqchip/apple-aic: Skip unnecessary enabling of use_fast_ipi
dt-bindings: apple,aic: Document A7-A11 compatibles
irqdomain: Use IS_ERR_OR_NULL() in irq_domain_trim_hierarchy()
genirq/msi: Use kmemdup_array() instead of kmemdup()
genirq/proc: Change the return value for set affinity permission error
genirq/proc: Use irq_move_pending() in show_irq_affinity()
genirq/proc: Correctly set file permissions for affinity control files
genirq: Get rid of global lock in irq_do_set_affinity()
genirq: Fix typo in struct comment
irqchip/loongarch-avec: Add AVEC irqchip support
irqchip/loongson-pch-msi: Prepare get_pch_msi_handle() for AVECINTC
irqchip/loongson-eiointc: Rename CPUHP_AP_IRQ_LOONGARCH_STARTING
LoongArch: Architectural preparation for AVEC irqchip
LoongArch: Move irqchip function prototypes to irq-loongson.h
irqchip/loongson-pch-msi: Switch to MSI parent domains
softirq: Remove unused 'action' parameter from action callback
...
This commit is contained in:
+1
-1
@@ -198,7 +198,7 @@ __irq_startup_managed(struct irq_desc *desc, const struct cpumask *aff,
|
||||
|
||||
irqd_clr_managed_shutdown(d);
|
||||
|
||||
if (cpumask_any_and(aff, cpu_online_mask) >= nr_cpu_ids) {
|
||||
if (!cpumask_intersects(aff, cpu_online_mask)) {
|
||||
/*
|
||||
* Catch code which fiddles with enable_irq() on a managed
|
||||
* and potentially shutdown IRQ. Chained interrupt
|
||||
|
||||
@@ -37,7 +37,7 @@ static inline bool irq_needs_fixup(struct irq_data *d)
|
||||
* has been removed from the online mask already.
|
||||
*/
|
||||
if (cpumask_any_but(m, cpu) < nr_cpu_ids &&
|
||||
cpumask_any_and(m, cpu_online_mask) >= nr_cpu_ids) {
|
||||
!cpumask_intersects(m, cpu_online_mask)) {
|
||||
/*
|
||||
* If this happens then there was a missed IRQ fixup at some
|
||||
* point. Warn about it and enforce fixup.
|
||||
@@ -110,7 +110,7 @@ static bool migrate_one_irq(struct irq_desc *desc)
|
||||
if (maskchip && chip->irq_mask)
|
||||
chip->irq_mask(d);
|
||||
|
||||
if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
|
||||
if (!cpumask_intersects(affinity, cpu_online_mask)) {
|
||||
/*
|
||||
* If the interrupt is managed, then shut it down and leave
|
||||
* the affinity untouched.
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
struct irq_sim_work_ctx {
|
||||
struct irq_work work;
|
||||
int irq_base;
|
||||
unsigned int irq_count;
|
||||
unsigned long *pending;
|
||||
struct irq_domain *domain;
|
||||
|
||||
+124
-86
@@ -128,72 +128,98 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
|
||||
|
||||
static int irq_domain_set_name(struct irq_domain *domain,
|
||||
const struct fwnode_handle *fwnode,
|
||||
enum irq_domain_bus_token bus_token)
|
||||
static int alloc_name(struct irq_domain *domain, char *base, enum irq_domain_bus_token bus_token)
|
||||
{
|
||||
if (bus_token == DOMAIN_BUS_ANY)
|
||||
domain->name = kasprintf(GFP_KERNEL, "%s", base);
|
||||
else
|
||||
domain->name = kasprintf(GFP_KERNEL, "%s-%d", base, bus_token);
|
||||
if (!domain->name)
|
||||
return -ENOMEM;
|
||||
|
||||
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alloc_fwnode_name(struct irq_domain *domain, const struct fwnode_handle *fwnode,
|
||||
enum irq_domain_bus_token bus_token, const char *suffix)
|
||||
{
|
||||
const char *sep = suffix ? "-" : "";
|
||||
const char *suf = suffix ? : "";
|
||||
char *name;
|
||||
|
||||
if (bus_token == DOMAIN_BUS_ANY)
|
||||
name = kasprintf(GFP_KERNEL, "%pfw%s%s", fwnode, sep, suf);
|
||||
else
|
||||
name = kasprintf(GFP_KERNEL, "%pfw%s%s-%d", fwnode, sep, suf, bus_token);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* fwnode paths contain '/', which debugfs is legitimately unhappy
|
||||
* about. Replace them with ':', which does the trick and is not as
|
||||
* offensive as '\'...
|
||||
*/
|
||||
domain->name = strreplace(name, '/', ':');
|
||||
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alloc_unknown_name(struct irq_domain *domain, enum irq_domain_bus_token bus_token)
|
||||
{
|
||||
static atomic_t unknown_domains;
|
||||
struct irqchip_fwid *fwid;
|
||||
int id = atomic_inc_return(&unknown_domains);
|
||||
|
||||
if (bus_token == DOMAIN_BUS_ANY)
|
||||
domain->name = kasprintf(GFP_KERNEL, "unknown-%d", id);
|
||||
else
|
||||
domain->name = kasprintf(GFP_KERNEL, "unknown-%d-%d", id, bus_token);
|
||||
if (!domain->name)
|
||||
return -ENOMEM;
|
||||
|
||||
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int irq_domain_set_name(struct irq_domain *domain, const struct irq_domain_info *info)
|
||||
{
|
||||
enum irq_domain_bus_token bus_token = info->bus_token;
|
||||
const struct fwnode_handle *fwnode = info->fwnode;
|
||||
|
||||
if (is_fwnode_irqchip(fwnode)) {
|
||||
fwid = container_of(fwnode, struct irqchip_fwid, fwnode);
|
||||
struct irqchip_fwid *fwid = container_of(fwnode, struct irqchip_fwid, fwnode);
|
||||
|
||||
/*
|
||||
* The name_suffix is only intended to be used to avoid a name
|
||||
* collision when multiple domains are created for a single
|
||||
* device and the name is picked using a real device node.
|
||||
* (Typical use-case is regmap-IRQ controllers for devices
|
||||
* providing more than one physical IRQ.) There should be no
|
||||
* need to use name_suffix with irqchip-fwnode.
|
||||
*/
|
||||
if (info->name_suffix)
|
||||
return -EINVAL;
|
||||
|
||||
switch (fwid->type) {
|
||||
case IRQCHIP_FWNODE_NAMED:
|
||||
case IRQCHIP_FWNODE_NAMED_ID:
|
||||
domain->name = bus_token ?
|
||||
kasprintf(GFP_KERNEL, "%s-%d",
|
||||
fwid->name, bus_token) :
|
||||
kstrdup(fwid->name, GFP_KERNEL);
|
||||
if (!domain->name)
|
||||
return -ENOMEM;
|
||||
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
|
||||
break;
|
||||
return alloc_name(domain, fwid->name, bus_token);
|
||||
default:
|
||||
domain->name = fwid->name;
|
||||
if (bus_token) {
|
||||
domain->name = kasprintf(GFP_KERNEL, "%s-%d",
|
||||
fwid->name, bus_token);
|
||||
if (!domain->name)
|
||||
return -ENOMEM;
|
||||
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
|
||||
}
|
||||
break;
|
||||
if (bus_token != DOMAIN_BUS_ANY)
|
||||
return alloc_name(domain, fwid->name, bus_token);
|
||||
}
|
||||
} else if (is_of_node(fwnode) || is_acpi_device_node(fwnode) ||
|
||||
is_software_node(fwnode)) {
|
||||
char *name;
|
||||
|
||||
/*
|
||||
* fwnode paths contain '/', which debugfs is legitimately
|
||||
* unhappy about. Replace them with ':', which does
|
||||
* the trick and is not as offensive as '\'...
|
||||
*/
|
||||
name = bus_token ?
|
||||
kasprintf(GFP_KERNEL, "%pfw-%d", fwnode, bus_token) :
|
||||
kasprintf(GFP_KERNEL, "%pfw", fwnode);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
domain->name = strreplace(name, '/', ':');
|
||||
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
|
||||
} else if (is_of_node(fwnode) || is_acpi_device_node(fwnode) || is_software_node(fwnode)) {
|
||||
return alloc_fwnode_name(domain, fwnode, bus_token, info->name_suffix);
|
||||
}
|
||||
|
||||
if (!domain->name) {
|
||||
if (fwnode)
|
||||
pr_err("Invalid fwnode type for irqdomain\n");
|
||||
domain->name = bus_token ?
|
||||
kasprintf(GFP_KERNEL, "unknown-%d-%d",
|
||||
atomic_inc_return(&unknown_domains),
|
||||
bus_token) :
|
||||
kasprintf(GFP_KERNEL, "unknown-%d",
|
||||
atomic_inc_return(&unknown_domains));
|
||||
if (!domain->name)
|
||||
return -ENOMEM;
|
||||
domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
|
||||
}
|
||||
if (domain->name)
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
if (fwnode)
|
||||
pr_err("Invalid fwnode type for irqdomain\n");
|
||||
return alloc_unknown_name(domain, bus_token);
|
||||
}
|
||||
|
||||
static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info)
|
||||
@@ -211,7 +237,7 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info
|
||||
if (!domain)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
err = irq_domain_set_name(domain, info->fwnode, info->bus_token);
|
||||
err = irq_domain_set_name(domain, info);
|
||||
if (err) {
|
||||
kfree(domain);
|
||||
return ERR_PTR(err);
|
||||
@@ -267,13 +293,20 @@ static void irq_domain_free(struct irq_domain *domain)
|
||||
kfree(domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* irq_domain_instantiate() - Instantiate a new irq domain data structure
|
||||
* @info: Domain information pointer pointing to the information for this domain
|
||||
*
|
||||
* Return: A pointer to the instantiated irq domain or an ERR_PTR value.
|
||||
*/
|
||||
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
|
||||
static void irq_domain_instantiate_descs(const struct irq_domain_info *info)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_SPARSE_IRQ))
|
||||
return;
|
||||
|
||||
if (irq_alloc_descs(info->virq_base, info->virq_base, info->size,
|
||||
of_node_to_nid(to_of_node(info->fwnode))) < 0) {
|
||||
pr_info("Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
|
||||
info->virq_base);
|
||||
}
|
||||
}
|
||||
|
||||
static struct irq_domain *__irq_domain_instantiate(const struct irq_domain_info *info,
|
||||
bool cond_alloc_descs, bool force_associate)
|
||||
{
|
||||
struct irq_domain *domain;
|
||||
int err;
|
||||
@@ -306,6 +339,19 @@ struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
|
||||
|
||||
__irq_domain_publish(domain);
|
||||
|
||||
if (cond_alloc_descs && info->virq_base > 0)
|
||||
irq_domain_instantiate_descs(info);
|
||||
|
||||
/*
|
||||
* Legacy interrupt domains have a fixed Linux interrupt number
|
||||
* associated. Other interrupt domains can request association by
|
||||
* providing a Linux interrupt number > 0.
|
||||
*/
|
||||
if (force_associate || info->virq_base > 0) {
|
||||
irq_domain_associate_many(domain, info->virq_base, info->hwirq_base,
|
||||
info->size - info->hwirq_base);
|
||||
}
|
||||
|
||||
return domain;
|
||||
|
||||
err_domain_gc_remove:
|
||||
@@ -315,6 +361,17 @@ err_domain_free:
|
||||
irq_domain_free(domain);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/**
|
||||
* irq_domain_instantiate() - Instantiate a new irq domain data structure
|
||||
* @info: Domain information pointer pointing to the information for this domain
|
||||
*
|
||||
* Return: A pointer to the instantiated irq domain or an ERR_PTR value.
|
||||
*/
|
||||
struct irq_domain *irq_domain_instantiate(const struct irq_domain_info *info)
|
||||
{
|
||||
return __irq_domain_instantiate(info, false, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(irq_domain_instantiate);
|
||||
|
||||
/**
|
||||
@@ -413,28 +470,13 @@ struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode,
|
||||
.fwnode = fwnode,
|
||||
.size = size,
|
||||
.hwirq_max = size,
|
||||
.virq_base = first_irq,
|
||||
.ops = ops,
|
||||
.host_data = host_data,
|
||||
};
|
||||
struct irq_domain *domain;
|
||||
struct irq_domain *domain = __irq_domain_instantiate(&info, true, false);
|
||||
|
||||
domain = irq_domain_instantiate(&info);
|
||||
if (IS_ERR(domain))
|
||||
return NULL;
|
||||
|
||||
if (first_irq > 0) {
|
||||
if (IS_ENABLED(CONFIG_SPARSE_IRQ)) {
|
||||
/* attempt to allocated irq_descs */
|
||||
int rc = irq_alloc_descs(first_irq, first_irq, size,
|
||||
of_node_to_nid(to_of_node(fwnode)));
|
||||
if (rc < 0)
|
||||
pr_info("Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
|
||||
first_irq);
|
||||
}
|
||||
irq_domain_associate_many(domain, first_irq, 0, size);
|
||||
}
|
||||
|
||||
return domain;
|
||||
return IS_ERR(domain) ? NULL : domain;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(irq_domain_create_simple);
|
||||
|
||||
@@ -476,18 +518,14 @@ struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode,
|
||||
.fwnode = fwnode,
|
||||
.size = first_hwirq + size,
|
||||
.hwirq_max = first_hwirq + size,
|
||||
.hwirq_base = first_hwirq,
|
||||
.virq_base = first_irq,
|
||||
.ops = ops,
|
||||
.host_data = host_data,
|
||||
};
|
||||
struct irq_domain *domain;
|
||||
struct irq_domain *domain = __irq_domain_instantiate(&info, false, true);
|
||||
|
||||
domain = irq_domain_instantiate(&info);
|
||||
if (IS_ERR(domain))
|
||||
return NULL;
|
||||
|
||||
irq_domain_associate_many(domain, first_irq, first_hwirq, size);
|
||||
|
||||
return domain;
|
||||
return IS_ERR(domain) ? NULL : domain;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(irq_domain_create_legacy);
|
||||
|
||||
@@ -1365,7 +1403,7 @@ static int irq_domain_trim_hierarchy(unsigned int virq)
|
||||
tail = NULL;
|
||||
|
||||
/* The first entry must have a valid irqchip */
|
||||
if (!irq_data->chip || IS_ERR(irq_data->chip))
|
||||
if (IS_ERR_OR_NULL(irq_data->chip))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
|
||||
+9
-12
@@ -218,21 +218,20 @@ static void irq_validate_effective_affinity(struct irq_data *data)
|
||||
static inline void irq_validate_effective_affinity(struct irq_data *data) { }
|
||||
#endif
|
||||
|
||||
static DEFINE_PER_CPU(struct cpumask, __tmp_mask);
|
||||
|
||||
int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
|
||||
bool force)
|
||||
{
|
||||
struct cpumask *tmp_mask = this_cpu_ptr(&__tmp_mask);
|
||||
struct irq_desc *desc = irq_data_to_desc(data);
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(data);
|
||||
const struct cpumask *prog_mask;
|
||||
int ret;
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(tmp_mask_lock);
|
||||
static struct cpumask tmp_mask;
|
||||
|
||||
if (!chip || !chip->irq_set_affinity)
|
||||
return -EINVAL;
|
||||
|
||||
raw_spin_lock(&tmp_mask_lock);
|
||||
/*
|
||||
* If this is a managed interrupt and housekeeping is enabled on
|
||||
* it check whether the requested affinity mask intersects with
|
||||
@@ -258,11 +257,11 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
|
||||
|
||||
hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
|
||||
|
||||
cpumask_and(&tmp_mask, mask, hk_mask);
|
||||
if (!cpumask_intersects(&tmp_mask, cpu_online_mask))
|
||||
cpumask_and(tmp_mask, mask, hk_mask);
|
||||
if (!cpumask_intersects(tmp_mask, cpu_online_mask))
|
||||
prog_mask = mask;
|
||||
else
|
||||
prog_mask = &tmp_mask;
|
||||
prog_mask = tmp_mask;
|
||||
} else {
|
||||
prog_mask = mask;
|
||||
}
|
||||
@@ -272,16 +271,14 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
|
||||
* unless we are being asked to force the affinity (in which
|
||||
* case we do as we are told).
|
||||
*/
|
||||
cpumask_and(&tmp_mask, prog_mask, cpu_online_mask);
|
||||
if (!force && !cpumask_empty(&tmp_mask))
|
||||
ret = chip->irq_set_affinity(data, &tmp_mask, force);
|
||||
cpumask_and(tmp_mask, prog_mask, cpu_online_mask);
|
||||
if (!force && !cpumask_empty(tmp_mask))
|
||||
ret = chip->irq_set_affinity(data, tmp_mask, force);
|
||||
else if (force)
|
||||
ret = chip->irq_set_affinity(data, mask, force);
|
||||
else
|
||||
ret = -EINVAL;
|
||||
|
||||
raw_spin_unlock(&tmp_mask_lock);
|
||||
|
||||
switch (ret) {
|
||||
case IRQ_SET_MASK_OK:
|
||||
case IRQ_SET_MASK_OK_DONE:
|
||||
|
||||
@@ -26,7 +26,7 @@ bool irq_fixup_move_pending(struct irq_desc *desc, bool force_clear)
|
||||
* The outgoing CPU might be the last online target in a pending
|
||||
* interrupt move. If that's the case clear the pending move bit.
|
||||
*/
|
||||
if (cpumask_any_and(desc->pending_mask, cpu_online_mask) >= nr_cpu_ids) {
|
||||
if (!cpumask_intersects(desc->pending_mask, cpu_online_mask)) {
|
||||
irqd_clr_move_pending(data);
|
||||
return false;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ void irq_move_masked_irq(struct irq_data *idata)
|
||||
* For correct operation this depends on the caller
|
||||
* masking the irqs.
|
||||
*/
|
||||
if (cpumask_any_and(desc->pending_mask, cpu_online_mask) < nr_cpu_ids) {
|
||||
if (cpumask_intersects(desc->pending_mask, cpu_online_mask)) {
|
||||
int ret;
|
||||
|
||||
ret = irq_do_set_affinity(data, desc->pending_mask, false);
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ static struct msi_desc *msi_alloc_desc(struct device *dev, int nvec,
|
||||
desc->dev = dev;
|
||||
desc->nvec_used = nvec;
|
||||
if (affinity) {
|
||||
desc->affinity = kmemdup(affinity, nvec * sizeof(*desc->affinity), GFP_KERNEL);
|
||||
desc->affinity = kmemdup_array(affinity, nvec, sizeof(*desc->affinity), GFP_KERNEL);
|
||||
if (!desc->affinity) {
|
||||
kfree(desc);
|
||||
return NULL;
|
||||
|
||||
+10
-7
@@ -52,10 +52,8 @@ static int show_irq_affinity(int type, struct seq_file *m)
|
||||
case AFFINITY:
|
||||
case AFFINITY_LIST:
|
||||
mask = desc->irq_common_data.affinity;
|
||||
#ifdef CONFIG_GENERIC_PENDING_IRQ
|
||||
if (irqd_is_setaffinity_pending(&desc->irq_data))
|
||||
mask = desc->pending_mask;
|
||||
#endif
|
||||
if (irq_move_pending(&desc->irq_data))
|
||||
mask = irq_desc_get_pending_mask(desc);
|
||||
break;
|
||||
case EFFECTIVE:
|
||||
case EFFECTIVE_LIST:
|
||||
@@ -142,7 +140,7 @@ static ssize_t write_irq_affinity(int type, struct file *file,
|
||||
int err;
|
||||
|
||||
if (!irq_can_set_affinity_usr(irq) || no_irq_affinity)
|
||||
return -EIO;
|
||||
return -EPERM;
|
||||
|
||||
if (!zalloc_cpumask_var(&new_value, GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
@@ -362,8 +360,13 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
|
||||
goto out_unlock;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
umode_t umode = S_IRUGO;
|
||||
|
||||
if (irq_can_set_affinity_usr(desc->irq_data.irq))
|
||||
umode |= S_IWUSR;
|
||||
|
||||
/* create /proc/irq/<irq>/smp_affinity */
|
||||
proc_create_data("smp_affinity", 0644, desc->dir,
|
||||
proc_create_data("smp_affinity", umode, desc->dir,
|
||||
&irq_affinity_proc_ops, irqp);
|
||||
|
||||
/* create /proc/irq/<irq>/affinity_hint */
|
||||
@@ -371,7 +374,7 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
|
||||
irq_affinity_hint_proc_show, irqp);
|
||||
|
||||
/* create /proc/irq/<irq>/smp_affinity_list */
|
||||
proc_create_data("smp_affinity_list", 0644, desc->dir,
|
||||
proc_create_data("smp_affinity_list", umode, desc->dir,
|
||||
&irq_affinity_list_proc_ops, irqp);
|
||||
|
||||
proc_create_single_data("node", 0444, desc->dir, irq_node_proc_show,
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ static inline bool rcu_reclaim_tiny(struct rcu_head *head)
|
||||
}
|
||||
|
||||
/* Invoke the RCU callbacks whose grace period has elapsed. */
|
||||
static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused)
|
||||
static __latent_entropy void rcu_process_callbacks(void)
|
||||
{
|
||||
struct rcu_head *next, *list;
|
||||
unsigned long flags;
|
||||
|
||||
+1
-1
@@ -2855,7 +2855,7 @@ static __latent_entropy void rcu_core(void)
|
||||
queue_work_on(rdp->cpu, rcu_gp_wq, &rdp->strict_work);
|
||||
}
|
||||
|
||||
static void rcu_core_si(struct softirq_action *h)
|
||||
static void rcu_core_si(void)
|
||||
{
|
||||
rcu_core();
|
||||
}
|
||||
|
||||
+1
-1
@@ -12483,7 +12483,7 @@ out:
|
||||
* - indirectly from a remote scheduler_tick() for NOHZ idle balancing
|
||||
* through the SMP cross-call nohz_csd_func()
|
||||
*/
|
||||
static __latent_entropy void sched_balance_softirq(struct softirq_action *h)
|
||||
static __latent_entropy void sched_balance_softirq(void)
|
||||
{
|
||||
struct rq *this_rq = this_rq();
|
||||
enum cpu_idle_type idle = this_rq->idle_balance;
|
||||
|
||||
+7
-8
@@ -551,7 +551,7 @@ restart:
|
||||
kstat_incr_softirqs_this_cpu(vec_nr);
|
||||
|
||||
trace_softirq_entry(vec_nr);
|
||||
h->action(h);
|
||||
h->action();
|
||||
trace_softirq_exit(vec_nr);
|
||||
if (unlikely(prev_count != preempt_count())) {
|
||||
pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n",
|
||||
@@ -700,7 +700,7 @@ void __raise_softirq_irqoff(unsigned int nr)
|
||||
or_softirq_pending(1UL << nr);
|
||||
}
|
||||
|
||||
void open_softirq(int nr, void (*action)(struct softirq_action *))
|
||||
void open_softirq(int nr, void (*action)(void))
|
||||
{
|
||||
softirq_vec[nr].action = action;
|
||||
}
|
||||
@@ -760,8 +760,7 @@ static bool tasklet_clear_sched(struct tasklet_struct *t)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void tasklet_action_common(struct softirq_action *a,
|
||||
struct tasklet_head *tl_head,
|
||||
static void tasklet_action_common(struct tasklet_head *tl_head,
|
||||
unsigned int softirq_nr)
|
||||
{
|
||||
struct tasklet_struct *list;
|
||||
@@ -805,16 +804,16 @@ static void tasklet_action_common(struct softirq_action *a,
|
||||
}
|
||||
}
|
||||
|
||||
static __latent_entropy void tasklet_action(struct softirq_action *a)
|
||||
static __latent_entropy void tasklet_action(void)
|
||||
{
|
||||
workqueue_softirq_action(false);
|
||||
tasklet_action_common(a, this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ);
|
||||
tasklet_action_common(this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ);
|
||||
}
|
||||
|
||||
static __latent_entropy void tasklet_hi_action(struct softirq_action *a)
|
||||
static __latent_entropy void tasklet_hi_action(void)
|
||||
{
|
||||
workqueue_softirq_action(true);
|
||||
tasklet_action_common(a, this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ);
|
||||
tasklet_action_common(this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ);
|
||||
}
|
||||
|
||||
void tasklet_setup(struct tasklet_struct *t,
|
||||
|
||||
@@ -1757,7 +1757,7 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now,
|
||||
}
|
||||
}
|
||||
|
||||
static __latent_entropy void hrtimer_run_softirq(struct softirq_action *h)
|
||||
static __latent_entropy void hrtimer_run_softirq(void)
|
||||
{
|
||||
struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
|
||||
unsigned long flags;
|
||||
|
||||
+1
-1
@@ -2440,7 +2440,7 @@ static void run_timer_base(int index)
|
||||
/*
|
||||
* This function runs timers and the timer-tq in bottom half context.
|
||||
*/
|
||||
static __latent_entropy void run_timer_softirq(struct softirq_action *h)
|
||||
static __latent_entropy void run_timer_softirq(void)
|
||||
{
|
||||
run_timer_base(BASE_LOCAL);
|
||||
if (IS_ENABLED(CONFIG_NO_HZ_COMMON)) {
|
||||
|
||||
Reference in New Issue
Block a user