aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFUJITA Tomonori <tomof@acm.org>2006-01-13 19:05:44 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2006-01-14 11:55:17 -0500
commit56851698c23430f0f291d6e50da344e6b414f3b9 (patch)
treee051fccf90003b6057c961b1b954725f38413d02
parent3e97c7e6cda933e3a1b518a8100d155c532a3cfc (diff)
[SCSI] iscsi: data digest page cache usage fix
Users can write to a page while we are sending it and making digest calculations. This ends up causing us to retry the command when a digest error is later reported. By using sock_no_sendpage when data digests are calculated we can avoid a lot of (not all but it helps) the retries becuase sock_no_sendpage is not zero copy. Signed-off-by: Alex Aizman <itn780@yahoo.com> Signed-off-by: Dmitry Yusupov <dmitry_yus@yahoo.com> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/iscsi_tcp.c16
-rw-r--r--drivers/scsi/iscsi_tcp.h2
2 files changed, 11 insertions, 7 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index cd1491e52361..5e8b3135574c 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -1318,15 +1318,15 @@ iscsi_conn_restore_callbacks(struct iscsi_conn *conn)
1318 * to use tcp_sendmsg(). 1318 * to use tcp_sendmsg().
1319 */ 1319 */
1320static inline int 1320static inline int
1321iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags) 1321iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
1322{ 1322{
1323 struct socket *sk = conn->sock;
1323 int res; 1324 int res;
1324 1325
1325 if ((int)buf->sg.offset >= 0) { 1326 if ((int)buf->sg.offset >= 0) {
1326 int offset = buf->sg.offset + buf->sent; 1327 int offset = buf->sg.offset + buf->sent;
1327 1328
1328 /* tcp_sendpage */ 1329 res = conn->sendpage(sk, buf->sg.page, offset, size, flags);
1329 res = sk->ops->sendpage(sk, buf->sg.page, offset, size, flags);
1330 } else { 1330 } else {
1331 struct msghdr msg; 1331 struct msghdr msg;
1332 1332
@@ -1354,7 +1354,6 @@ iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags)
1354static inline int 1354static inline int
1355iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) 1355iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen)
1356{ 1356{
1357 struct socket *sk = conn->sock;
1358 int flags = 0; /* MSG_DONTWAIT; */ 1357 int flags = 0; /* MSG_DONTWAIT; */
1359 int res, size; 1358 int res, size;
1360 1359
@@ -1363,7 +1362,7 @@ iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen)
1363 if (buf->sent + size != buf->sg.length || datalen) 1362 if (buf->sent + size != buf->sg.length || datalen)
1364 flags |= MSG_MORE; 1363 flags |= MSG_MORE;
1365 1364
1366 res = iscsi_send(sk, buf, size, flags); 1365 res = iscsi_send(conn, buf, size, flags);
1367 debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res); 1366 debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res);
1368 if (res >= 0) { 1367 if (res >= 0) {
1369 conn->txdata_octets += res; 1368 conn->txdata_octets += res;
@@ -1394,7 +1393,6 @@ static inline int
1394iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, 1393iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
1395 int *count, int *sent) 1394 int *count, int *sent)
1396{ 1395{
1397 struct socket *sk = conn->sock;
1398 int flags = 0; /* MSG_DONTWAIT; */ 1396 int flags = 0; /* MSG_DONTWAIT; */
1399 int res, size; 1397 int res, size;
1400 1398
@@ -1405,7 +1403,7 @@ iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
1405 if (buf->sent + size != buf->sg.length || *count != size) 1403 if (buf->sent + size != buf->sg.length || *count != size)
1406 flags |= MSG_MORE; 1404 flags |= MSG_MORE;
1407 1405
1408 res = iscsi_send(sk, buf, size, flags); 1406 res = iscsi_send(conn, buf, size, flags);
1409 debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n", 1407 debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n",
1410 size, buf->sent, *count, *sent, res); 1408 size, buf->sent, *count, *sent, res);
1411 if (res >= 0) { 1409 if (res >= 0) {
@@ -2713,6 +2711,8 @@ iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh,
2713 */ 2711 */
2714 iscsi_conn_set_callbacks(conn); 2712 iscsi_conn_set_callbacks(conn);
2715 2713
2714 conn->sendpage = conn->sock->ops->sendpage;
2715
2716 /* 2716 /*
2717 * set receive state machine into initial state 2717 * set receive state machine into initial state
2718 */ 2718 */
@@ -3467,6 +3467,8 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
3467 if (conn->data_rx_tfm) 3467 if (conn->data_rx_tfm)
3468 crypto_free_tfm(conn->data_rx_tfm); 3468 crypto_free_tfm(conn->data_rx_tfm);
3469 } 3469 }
3470 conn->sendpage = conn->datadgst_en ?
3471 sock_no_sendpage : conn->sock->ops->sendpage;
3470 break; 3472 break;
3471 case ISCSI_PARAM_INITIAL_R2T_EN: 3473 case ISCSI_PARAM_INITIAL_R2T_EN:
3472 session->initial_r2t_en = value; 3474 session->initial_r2t_en = value;
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index 9badafe8820d..c8bb5b0bcb4b 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -191,6 +191,8 @@ struct iscsi_conn {
191 uint32_t sendpage_failures_cnt; 191 uint32_t sendpage_failures_cnt;
192 uint32_t discontiguous_hdr_cnt; 192 uint32_t discontiguous_hdr_cnt;
193 uint32_t eh_abort_cnt; 193 uint32_t eh_abort_cnt;
194
195 ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
194}; 196};
195 197
196struct iscsi_session { 198struct iscsi_session {