diff options
| author | Jens Axboe <axboe@kernel.dk> | 2021-04-06 09:17:22 -0600 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2021-04-06 09:17:22 -0600 |
| commit | 762d6bd27d57491bedbbf0464a27a43f387de788 (patch) | |
| tree | d911962d73d17a88110f4fbf7eb28b53563c2e35 /drivers/nvme/target/tcp.c | |
| parent | 80755855f808c27c7154937667436f30e47bc820 (diff) | |
| parent | 8609c63fce58e94d82f6b6bf29c7806062e2e867 (diff) | |
Merge tag 'nvme-5.13-2021-04-06' of git://git.infradead.org/nvme into for-5.13/drivers
Pull NVMe updates from Christoph:
"nvme updates for Linux 5.13
- fix handling of very large MDTS values (Bart Van Assche)
- retrigger ANA log update if group descriptor isn't found
(Hannes Reinecke)
- fix locking contexts in nvme-tcp and nvmet-tcp (Sagi Grimberg)
- return proper error code from discovery ctrl (Hou Pu)
- verify the SGLS field in nvmet-tcp and nvmet-fc (Max Gurtovoy)
- disallow passthru cmd from targeting a nsid != nsid of the block dev
(Niklas Cassel)
- do not allow model_number exceed 40 bytes in nvmet (Noam Gottlieb)
- enable optional queue idle period tracking in nvmet-tcp
(Mark Wunderlich)
- various cleanups and optimizations (Chaitanya Kulkarni, Kanchan Joshi)
- expose fast_io_fail_tmo in sysfs (Daniel Wagner)
- implement non-MDTS command limits (Keith Busch)
- reduce warnings for unhandled command effects (Keith Busch)
- allocate storage for the SQE as part of the nvme_request (Keith Busch)"
* tag 'nvme-5.13-2021-04-06' of git://git.infradead.org/nvme: (33 commits)
nvme: fix handling of large MDTS values
nvme: implement non-mdts command limits
nvme: disallow passthru cmd from targeting a nsid != nsid of the block dev
nvme: retrigger ANA log update if group descriptor isn't found
nvme: export fast_io_fail_tmo to sysfs
nvme: remove superfluous else in nvme_ctrl_loss_tmo_store
nvme: use sysfs_emit instead of sprintf
nvme-fc: check sgl supported by target
nvme-tcp: check sgl supported by target
nvmet-tcp: enable optional queue idle period tracking
nvmet-tcp: fix incorrect locking in state_change sk callback
nvme-tcp: block BH in sk state_change sk callback
nvmet: return proper error code from discovery ctrl
nvme: warn of unhandled effects only once
nvme: use driver pdu command for passthrough
nvme-pci: allocate nvme_command within driver pdu
nvmet: do not allow model_number exceed 40 bytes
nvmet: remove unnecessary ctrl parameter
nvmet-fc: update function documentation
nvme-fc: fix the function documentation comment
...
Diffstat (limited to 'drivers/nvme/target/tcp.c')
| -rw-r--r-- | drivers/nvme/target/tcp.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 8b0485ada315..558a973277fd 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -29,6 +29,16 @@ static int so_priority; module_param(so_priority, int, 0644); MODULE_PARM_DESC(so_priority, "nvmet tcp socket optimize priority"); +/* Define a time period (in usecs) that io_work() shall sample an activated + * queue before determining it to be idle. This optional module behavior + * can enable NIC solutions that support socket optimized packet processing + * using advanced interrupt moderation techniques. + */ +static int idle_poll_period_usecs; +module_param(idle_poll_period_usecs, int, 0644); +MODULE_PARM_DESC(idle_poll_period_usecs, + "nvmet tcp io_work poll till idle time period in usecs"); + #define NVMET_TCP_RECV_BUDGET 8 #define NVMET_TCP_SEND_BUDGET 8 #define NVMET_TCP_IO_WORK_BUDGET 64 @@ -119,6 +129,8 @@ struct nvmet_tcp_queue { struct ahash_request *snd_hash; struct ahash_request *rcv_hash; + unsigned long poll_end; + spinlock_t state_lock; enum nvmet_tcp_queue_state state; @@ -1216,6 +1228,23 @@ static void nvmet_tcp_schedule_release_queue(struct nvmet_tcp_queue *queue) spin_unlock(&queue->state_lock); } +static inline void nvmet_tcp_arm_queue_deadline(struct nvmet_tcp_queue *queue) +{ + queue->poll_end = jiffies + usecs_to_jiffies(idle_poll_period_usecs); +} + +static bool nvmet_tcp_check_queue_deadline(struct nvmet_tcp_queue *queue, + int ops) +{ + if (!idle_poll_period_usecs) + return false; + + if (ops) + nvmet_tcp_arm_queue_deadline(queue); + + return !time_after(jiffies, queue->poll_end); +} + static void nvmet_tcp_io_work(struct work_struct *w) { struct nvmet_tcp_queue *queue = @@ -1241,9 +1270,10 @@ static void nvmet_tcp_io_work(struct work_struct *w) } while (pending && ops < NVMET_TCP_IO_WORK_BUDGET); /* - * We exahusted our budget, requeue our selves + * Requeue the worker if idle deadline period is in progress or any + * ops activity was recorded during the do-while loop above. */ - if (pending) + if (nvmet_tcp_check_queue_deadline(queue, ops) || pending) queue_work_on(queue_cpu(queue), nvmet_tcp_wq, &queue->io_work); } @@ -1434,7 +1464,7 @@ static void nvmet_tcp_state_change(struct sock *sk) { struct nvmet_tcp_queue *queue; - write_lock_bh(&sk->sk_callback_lock); + read_lock_bh(&sk->sk_callback_lock); queue = sk->sk_user_data; if (!queue) goto done; @@ -1452,7 +1482,7 @@ static void nvmet_tcp_state_change(struct sock *sk) queue->idx, sk->sk_state); } done: - write_unlock_bh(&sk->sk_callback_lock); + read_unlock_bh(&sk->sk_callback_lock); } static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue) @@ -1501,6 +1531,8 @@ static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue) sock->sk->sk_state_change = nvmet_tcp_state_change; queue->write_space = sock->sk->sk_write_space; sock->sk->sk_write_space = nvmet_tcp_write_space; + if (idle_poll_period_usecs) + nvmet_tcp_arm_queue_deadline(queue); queue_work_on(queue_cpu(queue), nvmet_tcp_wq, &queue->io_work); } write_unlock_bh(&sock->sk->sk_callback_lock); |
