]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - rt-patches/0112-genirq-Allow-disabling-of-softirq-processing-in-irq-.patch
WAR:media:i2c:ov5693: add flip and mirror setting
[hercules2020/nv-tegra/linux-4.4.git] / rt-patches / 0112-genirq-Allow-disabling-of-softirq-processing-in-irq-.patch
1 From 317cb092cbabed65d888b6f75dfa2c99a1ebc051 Mon Sep 17 00:00:00 2001
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Tue, 31 Jan 2012 13:01:27 +0100
4 Subject: [PATCH 112/365] genirq: Allow disabling of softirq processing in irq
5  thread context
6
7 The processing of softirqs in irq thread context is a performance gain
8 for the non-rt workloads of a system, but it's counterproductive for
9 interrupts which are explicitely related to the realtime
10 workload. Allow such interrupts to prevent softirq processing in their
11 thread context.
12
13 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
14 ---
15  include/linux/interrupt.h |  2 ++
16  include/linux/irq.h       |  4 +++-
17  kernel/irq/manage.c       | 13 ++++++++++++-
18  kernel/irq/settings.h     | 12 ++++++++++++
19  kernel/softirq.c          |  9 +++++++++
20  5 files changed, 38 insertions(+), 2 deletions(-)
21
22 diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
23 index 7033381..47d38a0 100644
24 --- a/include/linux/interrupt.h
25 +++ b/include/linux/interrupt.h
26 @@ -61,6 +61,7 @@
27   *                interrupt handler after suspending interrupts. For system
28   *                wakeup devices users need to implement wakeup detection in
29   *                their interrupt handlers.
30 + * IRQF_NO_SOFTIRQ_CALL - Do not process softirqs in the irq thread context (RT)
31   */
32  #define IRQF_SHARED            0x00000080
33  #define IRQF_PROBE_SHARED      0x00000100
34 @@ -74,6 +75,7 @@
35  #define IRQF_NO_THREAD         0x00010000
36  #define IRQF_EARLY_RESUME      0x00020000
37  #define IRQF_COND_SUSPEND      0x00040000
38 +#define IRQF_NO_SOFTIRQ_CALL   0x00080000
39  
40  #define IRQF_TIMER             (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
41  
42 diff --git a/include/linux/irq.h b/include/linux/irq.h
43 index f7cade0..dac9e11 100644
44 --- a/include/linux/irq.h
45 +++ b/include/linux/irq.h
46 @@ -72,6 +72,7 @@ enum irqchip_irq_state;
47   * IRQ_IS_POLLED               - Always polled by another interrupt. Exclude
48   *                               it from the spurious interrupt detection
49   *                               mechanism and from core side polling.
50 + * IRQ_NO_SOFTIRQ_CALL         - No softirq processing in the irq thread context (RT)
51   * IRQ_DISABLE_UNLAZY          - Disable lazy irq disable
52   */
53  enum {
54 @@ -99,13 +100,14 @@ enum {
55         IRQ_PER_CPU_DEVID       = (1 << 17),
56         IRQ_IS_POLLED           = (1 << 18),
57         IRQ_DISABLE_UNLAZY      = (1 << 19),
58 +       IRQ_NO_SOFTIRQ_CALL     = (1 << 20),
59  };
60  
61  #define IRQF_MODIFY_MASK       \
62         (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
63          IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \
64          IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \
65 -        IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY)
66 +        IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY | IRQ_NO_SOFTIRQ_CALL)
67  
68  #define IRQ_NO_BALANCING_MASK  (IRQ_PER_CPU | IRQ_NO_BALANCING)
69  
70 diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
71 index 8842388..5b1ad63 100644
72 --- a/kernel/irq/manage.c
73 +++ b/kernel/irq/manage.c
74 @@ -940,7 +940,15 @@ irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action)
75         local_bh_disable();
76         ret = action->thread_fn(action->irq, action->dev_id);
77         irq_finalize_oneshot(desc, action);
78 -       local_bh_enable();
79 +       /*
80 +        * Interrupts which have real time requirements can be set up
81 +        * to avoid softirq processing in the thread handler. This is
82 +        * safe as these interrupts do not raise soft interrupts.
83 +        */
84 +       if (irq_settings_no_softirq_call(desc))
85 +               _local_bh_enable();
86 +       else
87 +               local_bh_enable();
88         return ret;
89  }
90  
91 @@ -1390,6 +1398,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
92                         irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
93                 }
94  
95 +               if (new->flags & IRQF_NO_SOFTIRQ_CALL)
96 +                       irq_settings_set_no_softirq_call(desc);
97 +
98                 /* Set default affinity mask once everything is setup */
99                 setup_affinity(desc, mask);
100  
101 diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h
102 index 320579d..2df2d44 100644
103 --- a/kernel/irq/settings.h
104 +++ b/kernel/irq/settings.h
105 @@ -16,6 +16,7 @@ enum {
106         _IRQ_PER_CPU_DEVID      = IRQ_PER_CPU_DEVID,
107         _IRQ_IS_POLLED          = IRQ_IS_POLLED,
108         _IRQ_DISABLE_UNLAZY     = IRQ_DISABLE_UNLAZY,
109 +       _IRQ_NO_SOFTIRQ_CALL    = IRQ_NO_SOFTIRQ_CALL,
110         _IRQF_MODIFY_MASK       = IRQF_MODIFY_MASK,
111  };
112  
113 @@ -30,6 +31,7 @@ enum {
114  #define IRQ_PER_CPU_DEVID      GOT_YOU_MORON
115  #define IRQ_IS_POLLED          GOT_YOU_MORON
116  #define IRQ_DISABLE_UNLAZY     GOT_YOU_MORON
117 +#define IRQ_NO_SOFTIRQ_CALL    GOT_YOU_MORON
118  #undef IRQF_MODIFY_MASK
119  #define IRQF_MODIFY_MASK       GOT_YOU_MORON
120  
121 @@ -40,6 +42,16 @@ irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set)
122         desc->status_use_accessors |= (set & _IRQF_MODIFY_MASK);
123  }
124  
125 +static inline bool irq_settings_no_softirq_call(struct irq_desc *desc)
126 +{
127 +       return desc->status_use_accessors & _IRQ_NO_SOFTIRQ_CALL;
128 +}
129 +
130 +static inline void irq_settings_set_no_softirq_call(struct irq_desc *desc)
131 +{
132 +       desc->status_use_accessors |= _IRQ_NO_SOFTIRQ_CALL;
133 +}
134 +
135  static inline bool irq_settings_is_per_cpu(struct irq_desc *desc)
136  {
137         return desc->status_use_accessors & _IRQ_PER_CPU;
138 diff --git a/kernel/softirq.c b/kernel/softirq.c
139 index 61de6e9..0fd9331 100644
140 --- a/kernel/softirq.c
141 +++ b/kernel/softirq.c
142 @@ -576,6 +576,15 @@ void __local_bh_enable(void)
143  }
144  EXPORT_SYMBOL(__local_bh_enable);
145  
146 +void _local_bh_enable(void)
147 +{
148 +       if (WARN_ON(current->softirq_nestcnt == 0))
149 +               return;
150 +       if (--current->softirq_nestcnt == 0)
151 +               migrate_enable();
152 +}
153 +EXPORT_SYMBOL(_local_bh_enable);
154 +
155  int in_serving_softirq(void)
156  {
157         return current->flags & PF_IN_SOFTIRQ;
158 -- 
159 2.7.4
160