diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 13:25:22 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 13:25:22 +0200 |
commit | 8a9ea3237e7eb5c25f09e429ad242ae5a3d5ea22 (patch) | |
tree | a0a63398a9983667d52cbbbf4e2405b4f22b1d83 /drivers/s390/cio/qdio_thinint.c | |
parent | 1be025d3cb40cd295123af2c394f7229ef9b30ca (diff) | |
parent | 8b3408f8ee994973869d8ba32c5bf482bc4ddca4 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1745 commits)
dp83640: free packet queues on remove
dp83640: use proper function to free transmit time stamping packets
ipv6: Do not use routes from locally generated RAs
|PATCH net-next] tg3: add tx_dropped counter
be2net: don't create multiple RX/TX rings in multi channel mode
be2net: don't create multiple TXQs in BE2
be2net: refactor VF setup/teardown code into be_vf_setup/clear()
be2net: add vlan/rx-mode/flow-control config to be_setup()
net_sched: cls_flow: use skb_header_pointer()
ipv4: avoid useless call of the function check_peer_pmtu
TCP: remove TCP_DEBUG
net: Fix driver name for mdio-gpio.c
ipv4: tcp: fix TOS value in ACK messages sent from TIME_WAIT
rtnetlink: Add missing manual netlink notification in dev_change_net_namespaces
ipv4: fix ipsec forward performance regression
jme: fix irq storm after suspend/resume
route: fix ICMP redirect validation
net: hold sock reference while processing tx timestamps
tcp: md5: add more const attributes
Add ethtool -g support to virtio_net
...
Fix up conflicts in:
- drivers/net/Kconfig:
The split-up generated a trivial conflict with removal of a
stale reference to Documentation/networking/net-modules.txt.
Remove it from the new location instead.
- fs/sysfs/dir.c:
Fairly nasty conflicts with the sysfs rb-tree usage, conflicting
with Eric Biederman's changes for tagged directories.
Diffstat (limited to 'drivers/s390/cio/qdio_thinint.c')
-rw-r--r-- | drivers/s390/cio/qdio_thinint.c | 88 |
1 files changed, 50 insertions, 38 deletions
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index 2a1d4dfaf85..a3e3949d7b6 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c @@ -67,12 +67,9 @@ static void put_indicator(u32 *addr) void tiqdio_add_input_queues(struct qdio_irq *irq_ptr) { - struct qdio_q *q; - int i; - mutex_lock(&tiq_list_lock); - for_each_input_queue(irq_ptr, q, i) - list_add_rcu(&q->entry, &tiq_list); + BUG_ON(irq_ptr->nr_input_qs < 1); + list_add_rcu(&irq_ptr->input_qs[0]->entry, &tiq_list); mutex_unlock(&tiq_list_lock); xchg(irq_ptr->dsci, 1 << 7); } @@ -80,19 +77,17 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr) void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr) { struct qdio_q *q; - int i; - for (i = 0; i < irq_ptr->nr_input_qs; i++) { - q = irq_ptr->input_qs[i]; - /* if establish triggered an error */ - if (!q || !q->entry.prev || !q->entry.next) - continue; + BUG_ON(irq_ptr->nr_input_qs < 1); + q = irq_ptr->input_qs[0]; + /* if establish triggered an error */ + if (!q || !q->entry.prev || !q->entry.next) + return; - mutex_lock(&tiq_list_lock); - list_del_rcu(&q->entry); - mutex_unlock(&tiq_list_lock); - synchronize_rcu(); - } + mutex_lock(&tiq_list_lock); + list_del_rcu(&q->entry); + mutex_unlock(&tiq_list_lock); + synchronize_rcu(); } static inline u32 clear_shared_ind(void) @@ -102,6 +97,40 @@ static inline u32 clear_shared_ind(void) return xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0); } +static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq) +{ + struct qdio_q *q; + int i; + + for_each_input_queue(irq, q, i) { + if (!references_shared_dsci(irq) && + has_multiple_inq_on_dsci(irq)) + xchg(q->irq_ptr->dsci, 0); + + if (q->u.in.queue_start_poll) { + /* skip if polling is enabled or already in work */ + if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)) { + qperf_inc(q, int_discarded); + continue; + } + + /* avoid dsci clear here, done after processing */ + q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr, + q->irq_ptr->int_parm); + } else { + if (!shared_ind(q)) + xchg(q->irq_ptr->dsci, 0); + + /* + * Call inbound processing but not directly + * since that could starve other thinint queues. + */ + tasklet_schedule(&q->tasklet); + } + } +} + /** * tiqdio_thinint_handler - thin interrupt handler for qdio * @alsi: pointer to adapter local summary indicator @@ -120,35 +149,18 @@ static void tiqdio_thinint_handler(void *alsi, void *data) /* check for work on all inbound thinint queues */ list_for_each_entry_rcu(q, &tiq_list, entry) { + struct qdio_irq *irq; /* only process queues from changed sets */ - if (unlikely(shared_ind(q->irq_ptr->dsci))) { + irq = q->irq_ptr; + if (unlikely(references_shared_dsci(irq))) { if (!si_used) continue; - } else if (!*q->irq_ptr->dsci) + } else if (!*irq->dsci) continue; - if (q->u.in.queue_start_poll) { - /* skip if polling is enabled or already in work */ - if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, - &q->u.in.queue_irq_state)) { - qperf_inc(q, int_discarded); - continue; - } + tiqdio_call_inq_handlers(irq); - /* avoid dsci clear here, done after processing */ - q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr, - q->irq_ptr->int_parm); - } else { - /* only clear it if the indicator is non-shared */ - if (!shared_ind(q->irq_ptr->dsci)) - xchg(q->irq_ptr->dsci, 0); - /* - * Call inbound processing but not directly - * since that could starve other thinint queues. - */ - tasklet_schedule(&q->tasklet); - } qperf_inc(q, adapter_int); } rcu_read_unlock(); |