linux/drivers/scsi/iscsi_tcp.h
Mike Christie f1d269765e scsi: iscsi: Run recv path from workqueue
We don't always want to run the recv path from the network softirq because
when we have to have multiple sessions sharing the same CPUs, some sessions
can eat up the NAPI softirq budget and affect other sessions or users.

Allow us to queue the recv handling to the iscsi workqueue so we can have
the scheduler/wq code try to balance the work and CPU use across all
sessions' worker threads.

Note: It wasn't the original intent of the change but a nice side effect is
that for some workloads/configs we get a nice performance boost. For a
simple read heavy test:

  fio --direct=1 --filename=/dev/dm-0  --rw=randread --bs=256K
    --ioengine=libaio --iodepth=128 --numjobs=4

where the iscsi threads, fio jobs, and rps_cpus share CPUs we see a 32%
throughput boost. We also see increases for small I/O IOPs tests but it's
not as high.

Link: https://lore.kernel.org/r/20220616224557.115234-4-michael.christie@oracle.com
Reviewed-by: Lee Duncan <lduncan@suse.com>
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2022-06-21 21:19:22 -04:00

62 lines
1.5 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* iSCSI Initiator TCP Transport
* Copyright (C) 2004 Dmitry Yusupov
* Copyright (C) 2004 Alex Aizman
* Copyright (C) 2005 - 2006 Mike Christie
* Copyright (C) 2006 Red Hat, Inc. All rights reserved.
* maintained by open-iscsi@googlegroups.com
*
* See the file COPYING included with this distribution for more details.
*/
#ifndef ISCSI_SW_TCP_H
#define ISCSI_SW_TCP_H
#include <scsi/libiscsi.h>
#include <scsi/libiscsi_tcp.h>
struct socket;
struct iscsi_tcp_conn;
/* Socket connection send helper */
struct iscsi_sw_tcp_send {
struct iscsi_hdr *hdr;
struct iscsi_segment segment;
struct iscsi_segment data_segment;
};
struct iscsi_sw_tcp_conn {
struct socket *sock;
struct work_struct recvwork;
bool queue_recv;
struct iscsi_sw_tcp_send out;
/* old values for socket callbacks */
void (*old_data_ready)(struct sock *);
void (*old_state_change)(struct sock *);
void (*old_write_space)(struct sock *);
/* data and header digests */
struct ahash_request *tx_hash; /* CRC32C (Tx) */
struct ahash_request *rx_hash; /* CRC32C (Rx) */
/* MIB custom statistics */
uint32_t sendpage_failures_cnt;
uint32_t discontiguous_hdr_cnt;
ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
};
struct iscsi_sw_tcp_host {
struct iscsi_session *session;
};
struct iscsi_sw_tcp_hdrbuf {
struct iscsi_hdr hdrbuf;
char hdrextbuf[ISCSI_MAX_AHS_SIZE +
ISCSI_DIGEST_SIZE];
};
#endif /* ISCSI_SW_TCP_H */