aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2013-09-03 08:12:07 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2013-09-04 11:19:10 -0400
commit50ce749d0d107aaed8c2d702b987529f978a40f7 (patch)
tree94da2a3fbbf017218da9931748db2a3373475fcf /arch
parent8237ac3c4c827a187538fab1ca370e34addc922d (diff)
s390/irq: use hlists for external interrupt handler array
Use hlists for the hashed array of external interrupt handlers. Reduces the size of the array by 50% (2KB). Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/kernel/irq.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index b34ba0ea96a9..4ecf017f697c 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -196,13 +196,13 @@ asmlinkage void do_softirq(void)
196 * ext_int_hash[index] is the list head for all external interrupts that hash 196 * ext_int_hash[index] is the list head for all external interrupts that hash
197 * to this index. 197 * to this index.
198 */ 198 */
199static struct list_head ext_int_hash[256]; 199static struct hlist_head ext_int_hash[256];
200 200
201struct ext_int_info { 201struct ext_int_info {
202 ext_int_handler_t handler; 202 ext_int_handler_t handler;
203 u16 code; 203 struct hlist_node entry;
204 struct list_head entry;
205 struct rcu_head rcu; 204 struct rcu_head rcu;
205 u16 code;
206}; 206};
207 207
208/* ext_int_hash_lock protects the handler lists for external interrupts */ 208/* ext_int_hash_lock protects the handler lists for external interrupts */
@@ -227,7 +227,7 @@ int register_external_interrupt(u16 code, ext_int_handler_t handler)
227 index = ext_hash(code); 227 index = ext_hash(code);
228 228
229 spin_lock_irqsave(&ext_int_hash_lock, flags); 229 spin_lock_irqsave(&ext_int_hash_lock, flags);
230 list_add_rcu(&p->entry, &ext_int_hash[index]); 230 hlist_add_head_rcu(&p->entry, &ext_int_hash[index]);
231 spin_unlock_irqrestore(&ext_int_hash_lock, flags); 231 spin_unlock_irqrestore(&ext_int_hash_lock, flags);
232 return 0; 232 return 0;
233} 233}
@@ -240,9 +240,9 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
240 int index = ext_hash(code); 240 int index = ext_hash(code);
241 241
242 spin_lock_irqsave(&ext_int_hash_lock, flags); 242 spin_lock_irqsave(&ext_int_hash_lock, flags);
243 list_for_each_entry_rcu(p, &ext_int_hash[index], entry) { 243 hlist_for_each_entry_rcu(p, &ext_int_hash[index], entry) {
244 if (p->code == code && p->handler == handler) { 244 if (p->code == code && p->handler == handler) {
245 list_del_rcu(&p->entry); 245 hlist_del_rcu(&p->entry);
246 kfree_rcu(p, rcu); 246 kfree_rcu(p, rcu);
247 } 247 }
248 } 248 }
@@ -264,12 +264,12 @@ static irqreturn_t do_ext_interrupt(int irq, void *dummy)
264 264
265 index = ext_hash(ext_code.code); 265 index = ext_hash(ext_code.code);
266 rcu_read_lock(); 266 rcu_read_lock();
267 list_for_each_entry_rcu(p, &ext_int_hash[index], entry) 267 hlist_for_each_entry_rcu(p, &ext_int_hash[index], entry) {
268 if (likely(p->code == ext_code.code)) 268 if (unlikely(p->code != ext_code.code))
269 p->handler(ext_code, regs->int_parm, 269 continue;
270 regs->int_parm_long); 270 p->handler(ext_code, regs->int_parm, regs->int_parm_long);
271 }
271 rcu_read_unlock(); 272 rcu_read_unlock();
272
273 return IRQ_HANDLED; 273 return IRQ_HANDLED;
274} 274}
275 275
@@ -283,7 +283,7 @@ void __init init_ext_interrupts(void)
283 int idx; 283 int idx;
284 284
285 for (idx = 0; idx < ARRAY_SIZE(ext_int_hash); idx++) 285 for (idx = 0; idx < ARRAY_SIZE(ext_int_hash); idx++)
286 INIT_LIST_HEAD(&ext_int_hash[idx]); 286 INIT_HLIST_HEAD(&ext_int_hash[idx]);
287 287
288 irq_set_chip_and_handler(EXT_INTERRUPT, 288 irq_set_chip_and_handler(EXT_INTERRUPT,
289 &dummy_irq_chip, handle_percpu_irq); 289 &dummy_irq_chip, handle_percpu_irq);