From 20658918dc214988fbbce6b46ec2ab006078e77a Mon Sep 17 00:00:00 2001
From: Vladislav Bolkhovitin Possible SCST improvements
@@ -52,12 +53,13 @@
which copy data from the page cache to the supplied buffer and back. Zero-copy FILEIO
would use page cache data directly. This would be a major performance improvement,
especially for fast hardware, like Infiniband, because it would eliminate the data copy
- latency. This proposal is limited for READs only, because for WRITEs it is a lot harder to
+ latency as well as considerably ease CPU and memory bandwidth load. This proposal is limited for
+ READs only, because for WRITEs it is a lot harder to
implement, so it is worth to do zero-copy for READs and WRITEs separately.
The main idea is to add one more flag to filp_open() "flags" parameter (like O_RDONLY, O_DIRECT, etc.) O_ZEROCOPY, which would be available - only if the caller is from the kernel space . In this case fd->f_op->readv(), + only if the caller is from the kernel space. In this case fd->f_op->readv(), do_sync_readv_writev(), etc. would receive as the pointer to data buffer not a real data buffer, but pointer to an empty SG vector. Then:
@@ -258,17 +260,18 @@That's all. Then only support for initiators, like iSCSI, which don't handle QUEUE FULL to decrease amount of queued - commands. Instead they expect target to control it through MAX_SN.
+ commands, should be added. Such initiators expect target to control size of + the queue, via, e.g., through MAX_SN for iSCSI. -For such cases at the stage 2 of the dynamic flow control development +
For it at the stage 2 of the dynamic flow control development the following should be done:
At the moment, in scst_vdisk handler command execution function vdisk_do_job() is + overcomplicated and not very performance effective. It would be good to replace all those + ugly "switch" statements by choosing the handler for each SCSI command by indirect + function call on an array of function pointers.
+ +I.e., there should be an array vdisk_exec_fns with 256 entries of function pointers:
+ +void (*cmd_exec_fn) (struct scst_cmd *cmd)
+ +Then vdisk_do_job() should look like
+ +static int vdisk_do_job(struct scst_cmd *cmd) +{ + return vdisk_exec_fns[cmd->cdb[0]](cmd); +}