Skip to content

Commit

Permalink
Merge tag 'irq-core-2020-12-23' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
 "This is the second attempt after the first one failed miserably and
  got zapped to unblock the rest of the interrupt related patches.

  A treewide cleanup of interrupt descriptor (ab)use with all sorts of
  racy accesses, inefficient and disfunctional code. The goal is to
  remove the export of irq_to_desc() to prevent these things from
  creeping up again"

* tag 'irq-core-2020-12-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (30 commits)
  genirq: Restrict export of irq_to_desc()
  xen/events: Implement irq distribution
  xen/events: Reduce irq_info:: Spurious_cnt storage size
  xen/events: Only force affinity mask for percpu interrupts
  xen/events: Use immediate affinity setting
  xen/events: Remove disfunct affinity spreading
  xen/events: Remove unused bind_evtchn_to_irq_lateeoi()
  net/mlx5: Use effective interrupt affinity
  net/mlx5: Replace irq_to_desc() abuse
  net/mlx4: Use effective interrupt affinity
  net/mlx4: Replace irq_to_desc() abuse
  PCI: mobiveil: Use irq_data_get_irq_chip_data()
  PCI: xilinx-nwl: Use irq_data_get_irq_chip_data()
  NTB/msi: Use irq_has_action()
  mfd: ab8500-debugfs: Remove the racy fiddling with irq_desc
  pinctrl: nomadik: Use irq_has_action()
  drm/i915/pmu: Replace open coded kstat_irqs() copy
  drm/i915/lpe_audio: Remove pointless irq_to_desc() usage
  s390/irq: Use irq_desc_kstat_cpu() in show_msi_interrupt()
  parisc/irq: Use irq_desc_kstat_cpu() in show_interrupts()
  ...
  • Loading branch information
torvalds committed Dec 24, 2020
2 parents 4a1106a + 64a1b95 commit 3913d00
Show file tree
Hide file tree
Showing 32 changed files with 281 additions and 228 deletions.
2 changes: 1 addition & 1 deletion arch/alpha/kernel/sys_jensen.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*
* Code supporting the Jensen.
*/

#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ void show_ipi_list(struct seq_file *p, int prec)
seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);

for_each_online_cpu(cpu)
seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu));
seq_printf(p, "%10u ", irq_desc_kstat_cpu(ipi_desc[i], cpu));

seq_printf(p, " %s\n", ipi_types[i]);
}
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
prec >= 4 ? " " : "");
for_each_online_cpu(cpu)
seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu));
seq_printf(p, "%10u ", irq_desc_kstat_cpu(ipi_desc[i], cpu));
seq_printf(p, " %s\n", ipi_types[i]);
}

Expand Down
7 changes: 2 additions & 5 deletions arch/parisc/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,9 @@ int show_interrupts(struct seq_file *p, void *v)
if (!action)
goto skip;
seq_printf(p, "%3d: ", i);
#ifdef CONFIG_SMP

for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#else
seq_printf(p, "%10u ", kstat_irqs(i));
#endif
seq_printf(p, "%10u ", irq_desc_kstat_cpu(desc, j));

seq_printf(p, " %14s", irq_desc_get_chip(desc)->name);
#ifndef PARISC_IRQ_CR16_COUNTS
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static void show_msi_interrupt(struct seq_file *p, int irq)
raw_spin_lock_irqsave(&desc->lock, flags);
seq_printf(p, "%3d: ", irq);
for_each_online_cpu(cpu)
seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu));
seq_printf(p, "%10u ", irq_desc_kstat_cpu(desc, cpu));

if (desc->irq_data.chip)
seq_printf(p, " %8s", desc->irq_data.chip->name);
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*
* Send feedback to <[email protected]>
*/
#include <linux/interrupt.h>
#include <linux/nodemask.h>
#include <linux/export.h>
#include <linux/mmzone.h>
Expand Down
4 changes: 0 additions & 4 deletions drivers/gpu/drm/i915/display/intel_lpe_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,13 +297,9 @@ int intel_lpe_audio_init(struct drm_i915_private *dev_priv)
*/
void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv)
{
struct irq_desc *desc;

if (!HAS_LPE_AUDIO(dev_priv))
return;

desc = irq_to_desc(dev_priv->lpe_audio.irq);

lpe_audio_platdev_destroy(dev_priv);

irq_free_desc(dev_priv->lpe_audio.irq);
Expand Down
34 changes: 34 additions & 0 deletions drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,24 @@
* and related files, but that will be described in separate chapters.
*/

/*
* Interrupt statistic for PMU. Increments the counter only if the
* interrupt originated from the the GPU so interrupts from a device which
* shares the interrupt line are not accounted.
*/
static inline void pmu_irq_stats(struct drm_i915_private *i915,
irqreturn_t res)
{
if (unlikely(res != IRQ_HANDLED))
return;

/*
* A clever compiler translates that into INC. A not so clever one
* should at least prevent store tearing.
*/
WRITE_ONCE(i915->pmu.irq_count, i915->pmu.irq_count + 1);
}

typedef bool (*long_pulse_detect_func)(enum hpd_pin pin, u32 val);
typedef u32 (*hotplug_enables_func)(struct drm_i915_private *i915,
enum hpd_pin pin);
Expand Down Expand Up @@ -1668,6 +1686,8 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
valleyview_pipestat_irq_handler(dev_priv, pipe_stats);
} while (0);

pmu_irq_stats(dev_priv, ret);

enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);

return ret;
Expand Down Expand Up @@ -1745,6 +1765,8 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
valleyview_pipestat_irq_handler(dev_priv, pipe_stats);
} while (0);

pmu_irq_stats(dev_priv, ret);

enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);

return ret;
Expand Down Expand Up @@ -2155,6 +2177,8 @@ static irqreturn_t ilk_irq_handler(int irq, void *arg)
if (sde_ier)
raw_reg_write(regs, SDEIER, sde_ier);

pmu_irq_stats(i915, ret);

/* IRQs are synced during runtime_suspend, we don't require a wakeref */
enable_rpm_wakeref_asserts(&i915->runtime_pm);

Expand Down Expand Up @@ -2541,6 +2565,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)

gen8_master_intr_enable(regs);

pmu_irq_stats(dev_priv, IRQ_HANDLED);

return IRQ_HANDLED;
}

Expand Down Expand Up @@ -2636,6 +2662,8 @@ __gen11_irq_handler(struct drm_i915_private * const i915,

gen11_gu_misc_irq_handler(gt, gu_misc_iir);

pmu_irq_stats(i915, IRQ_HANDLED);

return IRQ_HANDLED;
}

Expand Down Expand Up @@ -3934,6 +3962,8 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
i8xx_pipestat_irq_handler(dev_priv, iir, pipe_stats);
} while (0);

pmu_irq_stats(dev_priv, ret);

enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);

return ret;
Expand Down Expand Up @@ -4043,6 +4073,8 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
i915_pipestat_irq_handler(dev_priv, iir, pipe_stats);
} while (0);

pmu_irq_stats(dev_priv, ret);

enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);

return ret;
Expand Down Expand Up @@ -4189,6 +4221,8 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
i965_pipestat_irq_handler(dev_priv, iir, pipe_stats);
} while (0);

pmu_irq_stats(dev_priv, IRQ_HANDLED);

enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);

return ret;
Expand Down
19 changes: 1 addition & 18 deletions drivers/gpu/drm/i915/i915_pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* Copyright © 2017-2018 Intel Corporation
*/

#include <linux/irq.h>
#include <linux/pm_runtime.h>

#include "gt/intel_engine.h"
Expand Down Expand Up @@ -424,22 +423,6 @@ static enum hrtimer_restart i915_sample(struct hrtimer *hrtimer)
return HRTIMER_RESTART;
}

static u64 count_interrupts(struct drm_i915_private *i915)
{
/* open-coded kstat_irqs() */
struct irq_desc *desc = irq_to_desc(i915->drm.pdev->irq);
u64 sum = 0;
int cpu;

if (!desc || !desc->kstat_irqs)
return 0;

for_each_possible_cpu(cpu)
sum += *per_cpu_ptr(desc->kstat_irqs, cpu);

return sum;
}

static void i915_pmu_event_destroy(struct perf_event *event)
{
struct drm_i915_private *i915 =
Expand Down Expand Up @@ -590,7 +573,7 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
USEC_PER_SEC /* to MHz */);
break;
case I915_PMU_INTERRUPTS:
val = count_interrupts(i915);
val = READ_ONCE(pmu->irq_count);
break;
case I915_PMU_RC6_RESIDENCY:
val = get_rc6(&i915->gt);
Expand Down
8 changes: 8 additions & 0 deletions drivers/gpu/drm/i915/i915_pmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ struct i915_pmu {
* @sleep_last: Last time GT parked for RC6 estimation.
*/
ktime_t sleep_last;
/**
* @irq_count: Number of interrupts
*
* Intentionally unsigned long to avoid atomics or heuristics on 32bit.
* 4e9 interrupts are a lot and postprocessing can really deal with an
* occasional wraparound easily. It's 32bit after all.
*/
unsigned long irq_count;
/**
* @events_attr_group: Device events attribute group.
*/
Expand Down
16 changes: 3 additions & 13 deletions drivers/mfd/ab8500-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1513,24 +1513,14 @@ static int ab8500_interrupts_show(struct seq_file *s, void *p)
{
int line;

seq_puts(s, "name: number: number of: wake:\n");
seq_puts(s, "name: number: irq: number of: wake:\n");

for (line = 0; line < num_interrupt_lines; line++) {
struct irq_desc *desc = irq_to_desc(line + irq_first);

seq_printf(s, "%3i: %6i %4i",
seq_printf(s, "%3i: %4i %6i %4i\n",
line,
line + irq_first,
num_interrupts[line],
num_wake_interrupts[line]);

if (desc && desc->name)
seq_printf(s, "-%-8s", desc->name);
if (desc && desc->action) {
struct irqaction *action = desc->action;

seq_printf(s, " %s", action->name);
while ((action = action->next) != NULL)
seq_printf(s, ", %s", action->name);
}
seq_putc(s, '\n');
}
Expand Down
8 changes: 3 additions & 5 deletions drivers/net/ethernet/mellanox/mlx4/en_cq.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
int cq_idx)
{
struct mlx4_en_dev *mdev = priv->mdev;
int err = 0;
int irq, err = 0;
int timestamp_en = 0;
bool assigned_eq = false;

Expand All @@ -116,10 +116,8 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,

assigned_eq = true;
}

cq->irq_desc =
irq_to_desc(mlx4_eq_get_irq(mdev->dev,
cq->vector));
irq = mlx4_eq_get_irq(mdev->dev, cq->vector);
cq->aff_mask = irq_get_effective_affinity_mask(irq);
} else {
/* For TX we use the same irq per
ring we assigned for the RX */
Expand Down
6 changes: 1 addition & 5 deletions drivers/net/ethernet/mellanox/mlx4/en_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -958,18 +958,14 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)

/* If we used up all the quota - we're probably not done yet... */
if (done == budget || !clean_complete) {
const struct cpumask *aff;
struct irq_data *idata;
int cpu_curr;

/* in case we got here because of !clean_complete */
done = budget;

cpu_curr = smp_processor_id();
idata = irq_desc_get_irq_data(cq->irq_desc);
aff = irq_data_get_affinity_mask(idata);

if (likely(cpumask_test_cpu(cpu_curr, aff)))
if (likely(cpumask_test_cpu(cpu_curr, cq->aff_mask)))
return budget;

/* Current cpu is not according to smp_irq_affinity -
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#endif
#include <linux/cpu_rmap.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/irq.h>
#include <net/xdp.h>

#include <linux/mlx4/device.h>
Expand Down Expand Up @@ -365,7 +366,7 @@ struct mlx4_en_cq {
struct mlx4_cqe *buf;
#define MLX4_EN_OPCODE_ERROR 0x1e

struct irq_desc *irq_desc;
const struct cpumask *aff_mask;
};

struct mlx4_en_port_profile {
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ struct mlx5e_channel {
spinlock_t async_icosq_lock;

/* data path - accessed per napi poll */
struct irq_desc *irq_desc;
const struct cpumask *aff_mask;
struct mlx5e_ch_stats *stats;

/* control */
Expand Down
1 change: 0 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,6 @@ int mlx5e_port_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
c->mkey_be = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key);
c->num_tc = params->num_tc;
c->stats = &priv->port_ptp_stats.ch;
c->irq_desc = irq_to_desc(irq);
c->lag_port = lag_port;

netif_napi_add(netdev, &c->napi, mlx5e_ptp_napi_poll, 64);
Expand Down
1 change: 0 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ struct mlx5e_port_ptp {
u8 lag_port;

/* data path - accessed per napi poll */
struct irq_desc *irq_desc;
struct mlx5e_ch_stats *stats;

/* control */
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1987,7 +1987,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
c->num_tc = params->num_tc;
c->xdp = !!params->xdp_prog;
c->stats = &priv->channel_stats[ix].ch;
c->irq_desc = irq_to_desc(irq);
c->aff_mask = irq_get_effective_affinity_mask(irq);
c->lag_port = mlx5e_enumerate_lag_port(priv->mdev, ix);

netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64);
Expand Down
6 changes: 1 addition & 5 deletions drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,8 @@
static inline bool mlx5e_channel_no_affinity_change(struct mlx5e_channel *c)
{
int current_cpu = smp_processor_id();
const struct cpumask *aff;
struct irq_data *idata;

idata = irq_desc_get_irq_data(c->irq_desc);
aff = irq_data_get_affinity_mask(idata);
return cpumask_test_cpu(current_cpu, aff);
return cpumask_test_cpu(current_cpu, c->aff_mask);
}

static void mlx5e_handle_tx_dim(struct mlx5e_txqsq *sq)
Expand Down
4 changes: 1 addition & 3 deletions drivers/ntb/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,15 +282,13 @@ int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler,
struct ntb_msi_desc *msi_desc)
{
struct msi_desc *entry;
struct irq_desc *desc;
int ret;

if (!ntb->msi)
return -EINVAL;

for_each_pci_msi_entry(entry, ntb->pdev) {
desc = irq_to_desc(entry->irq);
if (desc->action)
if (irq_has_action(entry->irq))
continue;

ret = devm_request_threaded_irq(&ntb->dev, entry->irq, handler,
Expand Down
Loading

0 comments on commit 3913d00

Please sign in to comment.