optimize performance: reduce allocations, buffered I/O, and zero-copy reads

- Read path: eliminate redundant allocation in bsPerformCommand - remove
  the pre-allocation before bs.Read() and the append loop for zero-fill,
  use direct copy and in-place zero-fill instead
- parseHeader: use command pool (getCommand) instead of direct allocation,
  reducing GC pressure on the hot path
- Unmap: use a shared 1MB zero buffer instead of allocating per-descriptor,
  dramatically reducing allocations for large unmap operations
- Network I/O: add 256KB bufio.Writer to iSCSI connections, batching
  small PDU writes into fewer syscalls. Flush after txHandler completes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lei Xue
2026-03-14 19:03:30 +08:00
parent 729b450ac9
commit 16108ced95
5 changed files with 41 additions and 10 deletions

View File

@@ -109,7 +109,6 @@ func bsPerformCommand(bs api.BackingStore, cmd *api.SCSICommand) (err error, key
// TODO
break
case api.READ_6, api.READ_10, api.READ_12, api.READ_16:
rbuf = make([]byte, int(tl))
rbuf, err = bs.Read(int64(offset), tl)
if err != nil && err != io.EOF {
key = MEDIUM_ERROR
@@ -117,9 +116,6 @@ func bsPerformCommand(bs api.BackingStore, cmd *api.SCSICommand) (err error, key
break
}
length = len(rbuf)
for i := 0; i < int(tl)-length; i++ {
rbuf = append(rbuf, 0)
}
if (opcode != api.READ_6) && (scb[1]&0x10 != 0) {
bs.DataAdvise(int64(offset), int64(length), util.POSIX_FADV_NOREUSE)
@@ -131,6 +127,12 @@ func bsPerformCommand(bs api.BackingStore, cmd *api.SCSICommand) (err error, key
goto sense
}
copy(cmd.InSDBBuffer.Buffer, rbuf)
// Zero-fill any remaining bytes if read was short
if length < int(tl) {
for i := length; i < int(tl) && i < len(cmd.InSDBBuffer.Buffer); i++ {
cmd.InSDBBuffer.Buffer[i] = 0
}
}
case api.PRE_FETCH_10, api.PRE_FETCH_16:
err = bs.DataAdvise(int64(offset), tl, util.POSIX_FADV_WILLNEED)
if err != nil {