Commit ed47155b authored by Julian Wiedmann's avatar Julian Wiedmann Committed by David S. Miller

s390/qeth: fine-tune spinlocks

For quite a lot of code paths it's obvious that they will never run in
IRQ context. So replace their spin_lock_irqsave() calls with
spin_lock_irq().

While at it, get rid of the redundant card pointer in struct qeth_reply
that was used by qeth_send_control_data() to access the card's lock.
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 31c92732
...@@ -639,7 +639,6 @@ struct qeth_reply { ...@@ -639,7 +639,6 @@ struct qeth_reply {
atomic_t received; atomic_t received;
int rc; int rc;
void *param; void *param;
struct qeth_card *card;
refcount_t refcnt; refcount_t refcnt;
}; };
......
...@@ -592,7 +592,6 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) ...@@ -592,7 +592,6 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
if (reply) { if (reply) {
refcount_set(&reply->refcnt, 1); refcount_set(&reply->refcnt, 1);
atomic_set(&reply->received, 0); atomic_set(&reply->received, 0);
reply->card = card;
} }
return reply; return reply;
} }
...@@ -1541,15 +1540,14 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev) ...@@ -1541,15 +1540,14 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev)
static int qeth_clear_channel(struct qeth_channel *channel) static int qeth_clear_channel(struct qeth_channel *channel)
{ {
unsigned long flags;
struct qeth_card *card; struct qeth_card *card;
int rc; int rc;
card = CARD_FROM_CDEV(channel->ccwdev); card = CARD_FROM_CDEV(channel->ccwdev);
QETH_CARD_TEXT(card, 3, "clearch"); QETH_CARD_TEXT(card, 3, "clearch");
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
rc = ccw_device_clear(channel->ccwdev, QETH_CLEAR_CHANNEL_PARM); rc = ccw_device_clear(channel->ccwdev, QETH_CLEAR_CHANNEL_PARM);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
if (rc) if (rc)
return rc; return rc;
...@@ -1565,15 +1563,14 @@ static int qeth_clear_channel(struct qeth_channel *channel) ...@@ -1565,15 +1563,14 @@ static int qeth_clear_channel(struct qeth_channel *channel)
static int qeth_halt_channel(struct qeth_channel *channel) static int qeth_halt_channel(struct qeth_channel *channel)
{ {
unsigned long flags;
struct qeth_card *card; struct qeth_card *card;
int rc; int rc;
card = CARD_FROM_CDEV(channel->ccwdev); card = CARD_FROM_CDEV(channel->ccwdev);
QETH_CARD_TEXT(card, 3, "haltch"); QETH_CARD_TEXT(card, 3, "haltch");
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
rc = ccw_device_halt(channel->ccwdev, QETH_HALT_CHANNEL_PARM); rc = ccw_device_halt(channel->ccwdev, QETH_HALT_CHANNEL_PARM);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
if (rc) if (rc)
return rc; return rc;
...@@ -1667,7 +1664,6 @@ static int qeth_read_conf_data(struct qeth_card *card, void **buffer, ...@@ -1667,7 +1664,6 @@ static int qeth_read_conf_data(struct qeth_card *card, void **buffer,
char *rcd_buf; char *rcd_buf;
int ret; int ret;
struct qeth_channel *channel = &card->data; struct qeth_channel *channel = &card->data;
unsigned long flags;
/* /*
* scan for RCD command in extended SenseID data * scan for RCD command in extended SenseID data
...@@ -1681,11 +1677,11 @@ static int qeth_read_conf_data(struct qeth_card *card, void **buffer, ...@@ -1681,11 +1677,11 @@ static int qeth_read_conf_data(struct qeth_card *card, void **buffer,
qeth_setup_ccw(channel->ccw, ciw->cmd, ciw->count, rcd_buf); qeth_setup_ccw(channel->ccw, ciw->cmd, ciw->count, rcd_buf);
channel->state = CH_STATE_RCD; channel->state = CH_STATE_RCD;
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
ret = ccw_device_start_timeout(channel->ccwdev, channel->ccw, ret = ccw_device_start_timeout(channel->ccwdev, channel->ccw,
QETH_RCD_PARM, LPM_ANYPATH, 0, QETH_RCD_PARM, LPM_ANYPATH, 0,
QETH_RCD_TIMEOUT); QETH_RCD_TIMEOUT);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
if (!ret) if (!ret)
wait_event(card->wait_q, wait_event(card->wait_q,
(channel->state == CH_STATE_RCD_DONE || (channel->state == CH_STATE_RCD_DONE ||
...@@ -1843,7 +1839,6 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, ...@@ -1843,7 +1839,6 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel,
struct qeth_cmd_buffer *)) struct qeth_cmd_buffer *))
{ {
struct qeth_cmd_buffer *iob; struct qeth_cmd_buffer *iob;
unsigned long flags;
int rc; int rc;
struct qeth_card *card; struct qeth_card *card;
...@@ -1858,10 +1853,10 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, ...@@ -1858,10 +1853,10 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel,
wait_event(card->wait_q, wait_event(card->wait_q,
atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0); atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
QETH_DBF_TEXT(SETUP, 6, "noirqpnd"); QETH_DBF_TEXT(SETUP, 6, "noirqpnd");
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw, rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw,
(addr_t) iob, 0, 0, QETH_TIMEOUT); (addr_t) iob, 0, 0, QETH_TIMEOUT);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
if (rc) { if (rc) {
QETH_DBF_MESSAGE(2, "Error2 in activating channel rc=%d\n", rc); QETH_DBF_MESSAGE(2, "Error2 in activating channel rc=%d\n", rc);
...@@ -1888,7 +1883,6 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, ...@@ -1888,7 +1883,6 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel,
{ {
struct qeth_card *card; struct qeth_card *card;
struct qeth_cmd_buffer *iob; struct qeth_cmd_buffer *iob;
unsigned long flags;
__u16 temp; __u16 temp;
__u8 tmp; __u8 tmp;
int rc; int rc;
...@@ -1928,10 +1922,10 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, ...@@ -1928,10 +1922,10 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel,
wait_event(card->wait_q, wait_event(card->wait_q,
atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0); atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
QETH_DBF_TEXT(SETUP, 6, "noirqpnd"); QETH_DBF_TEXT(SETUP, 6, "noirqpnd");
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw, rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw,
(addr_t) iob, 0, 0, QETH_TIMEOUT); (addr_t) iob, 0, 0, QETH_TIMEOUT);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
if (rc) { if (rc) {
QETH_DBF_MESSAGE(2, "Error1 in activating channel. rc=%d\n", QETH_DBF_MESSAGE(2, "Error1 in activating channel. rc=%d\n",
...@@ -2112,7 +2106,6 @@ int qeth_send_control_data(struct qeth_card *card, int len, ...@@ -2112,7 +2106,6 @@ int qeth_send_control_data(struct qeth_card *card, int len,
{ {
struct qeth_channel *channel = iob->channel; struct qeth_channel *channel = iob->channel;
int rc; int rc;
unsigned long flags;
struct qeth_reply *reply = NULL; struct qeth_reply *reply = NULL;
unsigned long timeout, event_timeout; unsigned long timeout, event_timeout;
struct qeth_ipa_cmd *cmd = NULL; struct qeth_ipa_cmd *cmd = NULL;
...@@ -2145,26 +2138,26 @@ int qeth_send_control_data(struct qeth_card *card, int len, ...@@ -2145,26 +2138,26 @@ int qeth_send_control_data(struct qeth_card *card, int len,
} }
qeth_prepare_control_data(card, len, iob); qeth_prepare_control_data(card, len, iob);
spin_lock_irqsave(&card->lock, flags); spin_lock_irq(&card->lock);
list_add_tail(&reply->list, &card->cmd_waiter_list); list_add_tail(&reply->list, &card->cmd_waiter_list);
spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irq(&card->lock);
timeout = jiffies + event_timeout; timeout = jiffies + event_timeout;
QETH_CARD_TEXT(card, 6, "noirqpnd"); QETH_CARD_TEXT(card, 6, "noirqpnd");
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw, rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw,
(addr_t) iob, 0, 0, event_timeout); (addr_t) iob, 0, 0, event_timeout);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
if (rc) { if (rc) {
QETH_DBF_MESSAGE(2, "%s qeth_send_control_data: " QETH_DBF_MESSAGE(2, "%s qeth_send_control_data: "
"ccw_device_start rc = %i\n", "ccw_device_start rc = %i\n",
dev_name(&channel->ccwdev->dev), rc); dev_name(&channel->ccwdev->dev), rc);
QETH_CARD_TEXT_(card, 2, " err%d", rc); QETH_CARD_TEXT_(card, 2, " err%d", rc);
spin_lock_irqsave(&card->lock, flags); spin_lock_irq(&card->lock);
list_del_init(&reply->list); list_del_init(&reply->list);
qeth_put_reply(reply); qeth_put_reply(reply);
spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irq(&card->lock);
qeth_release_buffer(channel, iob); qeth_release_buffer(channel, iob);
atomic_set(&channel->irq_pending, 0); atomic_set(&channel->irq_pending, 0);
wake_up(&card->wait_q); wake_up(&card->wait_q);
...@@ -2192,9 +2185,9 @@ int qeth_send_control_data(struct qeth_card *card, int len, ...@@ -2192,9 +2185,9 @@ int qeth_send_control_data(struct qeth_card *card, int len,
time_err: time_err:
reply->rc = -ETIME; reply->rc = -ETIME;
spin_lock_irqsave(&reply->card->lock, flags); spin_lock_irq(&card->lock);
list_del_init(&reply->list); list_del_init(&reply->list);
spin_unlock_irqrestore(&reply->card->lock, flags); spin_unlock_irq(&card->lock);
atomic_inc(&reply->received); atomic_inc(&reply->received);
rc = reply->rc; rc = reply->rc;
qeth_put_reply(reply); qeth_put_reply(reply);
...@@ -5776,7 +5769,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5776,7 +5769,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
struct device *dev; struct device *dev;
int rc; int rc;
enum qeth_discipline_id enforced_disc; enum qeth_discipline_id enforced_disc;
unsigned long flags;
char dbf_name[DBF_NAME_LEN]; char dbf_name[DBF_NAME_LEN];
QETH_DBF_TEXT(SETUP, 2, "probedev"); QETH_DBF_TEXT(SETUP, 2, "probedev");
...@@ -5834,9 +5826,9 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5834,9 +5826,9 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
break; break;
} }
write_lock_irqsave(&qeth_core_card_list.rwlock, flags); write_lock_irq(&qeth_core_card_list.rwlock);
list_add_tail(&card->list, &qeth_core_card_list.list); list_add_tail(&card->list, &qeth_core_card_list.list);
write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags); write_unlock_irq(&qeth_core_card_list.rwlock);
return 0; return 0;
err_disc: err_disc:
...@@ -5852,7 +5844,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5852,7 +5844,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
static void qeth_core_remove_device(struct ccwgroup_device *gdev) static void qeth_core_remove_device(struct ccwgroup_device *gdev)
{ {
unsigned long flags;
struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct qeth_card *card = dev_get_drvdata(&gdev->dev);
QETH_DBF_TEXT(SETUP, 2, "removedv"); QETH_DBF_TEXT(SETUP, 2, "removedv");
...@@ -5862,9 +5853,9 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) ...@@ -5862,9 +5853,9 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
qeth_core_free_discipline(card); qeth_core_free_discipline(card);
} }
write_lock_irqsave(&qeth_core_card_list.rwlock, flags); write_lock_irq(&qeth_core_card_list.rwlock);
list_del(&card->list); list_del(&card->list);
write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags); write_unlock_irq(&qeth_core_card_list.rwlock);
free_netdev(card->dev); free_netdev(card->dev);
qeth_core_free_card(card); qeth_core_free_card(card);
dev_set_drvdata(&gdev->dev, NULL); dev_set_drvdata(&gdev->dev, NULL);
......
...@@ -1209,7 +1209,6 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len, ...@@ -1209,7 +1209,6 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len,
struct qeth_cmd_buffer *iob) struct qeth_cmd_buffer *iob)
{ {
struct qeth_channel *channel = iob->channel; struct qeth_channel *channel = iob->channel;
unsigned long flags;
int rc = 0; int rc = 0;
QETH_CARD_TEXT(card, 5, "osndctrd"); QETH_CARD_TEXT(card, 5, "osndctrd");
...@@ -1218,10 +1217,10 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len, ...@@ -1218,10 +1217,10 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len,
atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0); atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
qeth_prepare_control_data(card, len, iob); qeth_prepare_control_data(card, len, iob);
QETH_CARD_TEXT(card, 6, "osnoirqp"); QETH_CARD_TEXT(card, 6, "osnoirqp");
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw, rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw,
(addr_t) iob, 0, 0, QETH_IPA_TIMEOUT); (addr_t) iob, 0, 0, QETH_IPA_TIMEOUT);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
if (rc) { if (rc) {
QETH_DBF_MESSAGE(2, "qeth_osn_send_control_data: " QETH_DBF_MESSAGE(2, "qeth_osn_send_control_data: "
"ccw_device_start rc = %i\n", rc); "ccw_device_start rc = %i\n", rc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment