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:
@@ -312,8 +312,7 @@ func parseHeader(data []byte) (*ISCSICommand, error) {
|
||||
if len(data) != BHS_SIZE {
|
||||
return nil, fmt.Errorf("garbled header")
|
||||
}
|
||||
// TODO: sync.Pool
|
||||
m := &ISCSICommand{}
|
||||
m := getCommand()
|
||||
m.Immediate = 0x40&data[0] == 0x40
|
||||
m.OpCode = OpCode(data[0] & ISCSI_OPCODE_MASK)
|
||||
m.Final = 0x80&data[1] == 0x80
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package iscsit
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"net"
|
||||
"sort"
|
||||
@@ -61,6 +62,7 @@ type iscsiConnection struct {
|
||||
txIOState int
|
||||
refcount int
|
||||
conn net.Conn
|
||||
writer *bufio.Writer
|
||||
|
||||
rxBuffer []byte
|
||||
txBuffer []byte
|
||||
@@ -117,6 +119,7 @@ func (c *iscsiConnection) init() {
|
||||
c.state = CONN_STATE_FREE
|
||||
c.refcount = 1
|
||||
c.readLock = new(sync.RWMutex)
|
||||
c.writer = bufio.NewWriterSize(c.conn, 256*1024)
|
||||
c.loginParam.sessionParam = []ISCSISessionParam{}
|
||||
c.loginParam.tgtCSG = LoginOperationalNegotiation
|
||||
c.loginParam.tgtNSG = LoginOperationalNegotiation
|
||||
@@ -136,10 +139,15 @@ func (c *iscsiConnection) readData(buf []byte) (int, error) {
|
||||
}
|
||||
|
||||
func (c *iscsiConnection) write(resp []byte) (int, error) {
|
||||
return c.conn.Write(resp)
|
||||
return c.writer.Write(resp)
|
||||
}
|
||||
|
||||
func (c *iscsiConnection) flush() error {
|
||||
return c.writer.Flush()
|
||||
}
|
||||
|
||||
func (c *iscsiConnection) close() {
|
||||
c.writer.Flush()
|
||||
c.conn.Close()
|
||||
}
|
||||
|
||||
|
||||
@@ -830,6 +830,13 @@ SendRemainingData:
|
||||
}
|
||||
}
|
||||
|
||||
// Flush buffered writes to the network
|
||||
if err := conn.flush(); err != nil {
|
||||
log.Errorf("failed to flush data to client: %v", err)
|
||||
conn.state = CONN_STATE_CLOSE
|
||||
return
|
||||
}
|
||||
|
||||
log.Debugf("connection state: %v", conn.State())
|
||||
switch conn.state {
|
||||
case CONN_STATE_CLOSE, CONN_STATE_EXIT:
|
||||
|
||||
Reference in New Issue
Block a user