diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2009-04-21 16:32:34 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-04-27 11:10:06 -0400 |
commit | 1393109f23f8ad753a60a3e461c6caa96d8524f3 (patch) | |
tree | bc9400d252da0470d0ae9fb210f9afbd5479764d /drivers/scsi | |
parent | dd0af9f94e54efb13ee050ebac11909215ef02c2 (diff) |
[SCSI] cxgb3i: fix cpu use abuse during writes
When doing a lot (128) of large writes (256K) we can hit the cxgb3_snd_win
check pretty easily. The driver's xmit thread then takes 100% of the cpu.
The driver should not be returning -EAGAIN for this problem. It should
be returing -ENOBUFS, then when the window is opened again it should
queue the xmit thread (it already wakes the xmit thread).
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/cxgb3i/cxgb3i_offload.c | 4 | ||||
-rw-r--r-- | drivers/scsi/cxgb3i/cxgb3i_pdu.c | 19 |
2 files changed, 13 insertions, 10 deletions
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index 4d8654cdbdae..e11c9c180f39 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c | |||
@@ -1737,7 +1737,7 @@ int cxgb3i_c3cn_send_pdus(struct s3_conn *c3cn, struct sk_buff *skb) | |||
1737 | c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n", | 1737 | c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n", |
1738 | c3cn, c3cn->write_seq, c3cn->snd_una, | 1738 | c3cn, c3cn->write_seq, c3cn->snd_una, |
1739 | cxgb3_snd_win); | 1739 | cxgb3_snd_win); |
1740 | err = -EAGAIN; | 1740 | err = -ENOBUFS; |
1741 | goto out_err; | 1741 | goto out_err; |
1742 | } | 1742 | } |
1743 | 1743 | ||
@@ -1775,6 +1775,8 @@ done: | |||
1775 | out_err: | 1775 | out_err: |
1776 | if (copied == 0 && err == -EPIPE) | 1776 | if (copied == 0 && err == -EPIPE) |
1777 | copied = c3cn->err ? c3cn->err : -EPIPE; | 1777 | copied = c3cn->err ? c3cn->err : -EPIPE; |
1778 | else | ||
1779 | copied = err; | ||
1778 | goto done; | 1780 | goto done; |
1779 | } | 1781 | } |
1780 | 1782 | ||
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c index 7eebc9a7cb35..709105071177 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c +++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.c | |||
@@ -400,17 +400,18 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) | |||
400 | return 0; | 400 | return 0; |
401 | } | 401 | } |
402 | 402 | ||
403 | if (err < 0 && err != -EAGAIN) { | 403 | if (err == -EAGAIN || err == -ENOBUFS) { |
404 | kfree_skb(skb); | 404 | /* reset skb to send when we are called again */ |
405 | cxgb3i_tx_debug("itt 0x%x, skb 0x%p, len %u/%u, xmit err %d.\n", | 405 | tdata->skb = skb; |
406 | task->itt, skb, skb->len, skb->data_len, err); | ||
407 | iscsi_conn_printk(KERN_ERR, task->conn, "xmit err %d.\n", err); | ||
408 | iscsi_conn_failure(task->conn, ISCSI_ERR_XMIT_FAILED); | ||
409 | return err; | 406 | return err; |
410 | } | 407 | } |
411 | /* reset skb to send when we are called again */ | 408 | |
412 | tdata->skb = skb; | 409 | kfree_skb(skb); |
413 | return -EAGAIN; | 410 | cxgb3i_tx_debug("itt 0x%x, skb 0x%p, len %u/%u, xmit err %d.\n", |
411 | task->itt, skb, skb->len, skb->data_len, err); | ||
412 | iscsi_conn_printk(KERN_ERR, task->conn, "xmit err %d.\n", err); | ||
413 | iscsi_conn_failure(task->conn, ISCSI_ERR_XMIT_FAILED); | ||
414 | return err; | ||
414 | } | 415 | } |
415 | 416 | ||
416 | int cxgb3i_pdu_init(void) | 417 | int cxgb3i_pdu_init(void) |