[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>
This commit is contained in:
committed by
James Bottomley
parent
dd0af9f94e
commit
1393109f23
@@ -1737,7 +1737,7 @@ int cxgb3i_c3cn_send_pdus(struct s3_conn *c3cn, struct sk_buff *skb)
|
|||||||
c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n",
|
c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n",
|
||||||
c3cn, c3cn->write_seq, c3cn->snd_una,
|
c3cn, c3cn->write_seq, c3cn->snd_una,
|
||||||
cxgb3_snd_win);
|
cxgb3_snd_win);
|
||||||
err = -EAGAIN;
|
err = -ENOBUFS;
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1775,6 +1775,8 @@ done:
|
|||||||
out_err:
|
out_err:
|
||||||
if (copied == 0 && err == -EPIPE)
|
if (copied == 0 && err == -EPIPE)
|
||||||
copied = c3cn->err ? c3cn->err : -EPIPE;
|
copied = c3cn->err ? c3cn->err : -EPIPE;
|
||||||
|
else
|
||||||
|
copied = err;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -400,17 +400,18 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err < 0 && err != -EAGAIN) {
|
if (err == -EAGAIN || err == -ENOBUFS) {
|
||||||
|
/* reset skb to send when we are called again */
|
||||||
|
tdata->skb = skb;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
cxgb3i_tx_debug("itt 0x%x, skb 0x%p, len %u/%u, xmit err %d.\n",
|
cxgb3i_tx_debug("itt 0x%x, skb 0x%p, len %u/%u, xmit err %d.\n",
|
||||||
task->itt, skb, skb->len, skb->data_len, err);
|
task->itt, skb, skb->len, skb->data_len, err);
|
||||||
iscsi_conn_printk(KERN_ERR, task->conn, "xmit err %d.\n", err);
|
iscsi_conn_printk(KERN_ERR, task->conn, "xmit err %d.\n", err);
|
||||||
iscsi_conn_failure(task->conn, ISCSI_ERR_XMIT_FAILED);
|
iscsi_conn_failure(task->conn, ISCSI_ERR_XMIT_FAILED);
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
/* reset skb to send when we are called again */
|
|
||||||
tdata->skb = skb;
|
|
||||||
return -EAGAIN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cxgb3i_pdu_init(void)
|
int cxgb3i_pdu_init(void)
|
||||||
|
Reference in New Issue
Block a user