1 From 166a05ce64a05218f51563d201644ab3bfddaacc Mon Sep 17 00:00:00 2001
2 From: Kienan Stewart <kstewart@efficios.com>
3 Date: Mon, 29 Jul 2024 14:23:02 +0000
4 Subject: [PATCH 6/6] Fix: scsi: sd: Atomic write support added in 6.11-rc1
8 commit bf4ae8f2e6407a779c0368eb0f3e047a8333be17
9 Author: John Garry <john.g.garry@oracle.com>
10 Date: Thu Jun 20 12:53:57 2024 +0000
12 scsi: sd: Atomic write support
14 Support is divided into two main areas:
15 - reading VPD pages and setting sdev request_queue limits
16 - support WRITE ATOMIC (16) command and tracing
18 The relevant block limits VPD page need to be read to allow the block layer
19 request_queue atomic write limits to be set. These VPD page limits are
20 described in sbc4r22 section 6.6.4 - Block limits VPD page.
22 There are five limits of interest:
23 - MAXIMUM ATOMIC TRANSFER LENGTH
25 - ATOMIC TRANSFER LENGTH GRANULARITY
26 - MAXIMUM ATOMIC TRANSFER LENGTH WITH BOUNDARY
27 - MAXIMUM ATOMIC BOUNDARY SIZE
29 MAXIMUM ATOMIC TRANSFER LENGTH is the maximum length for a WRITE ATOMIC
30 (16) command. It will not be greater than the device MAXIMUM TRANSFER
33 ATOMIC ALIGNMENT and ATOMIC TRANSFER LENGTH GRANULARITY are the minimum
34 alignment and length values for an atomic write in terms of logical blocks.
36 Unlike NVMe, SCSI does not specify an LBA space boundary, but does specify
37 a per-IO boundary granularity. The maximum boundary size is specified in
38 MAXIMUM ATOMIC BOUNDARY SIZE. When used, this boundary value is set in the
39 WRITE ATOMIC (16) ATOMIC BOUNDARY field - layout for the WRITE_ATOMIC_16
40 command can be found in sbc4r22 section 5.48. This boundary value is the
41 granularity size at which the device may atomically write the data. A value
42 of zero in WRITE ATOMIC (16) ATOMIC BOUNDARY field means that all data must
43 be atomically written together.
45 MAXIMUM ATOMIC TRANSFER LENGTH WITH BOUNDARY is the maximum atomic write
46 length if a non-zero boundary value is set.
48 For atomic write support, the WRITE ATOMIC (16) boundary is not of much
49 interest, as the block layer expects each request submitted to be executed
50 be atomically written together.
52 MAXIMUM ATOMIC TRANSFER LENGTH WITH BOUNDARY is the maximum atomic write
53 length if a non-zero boundary value is set.
55 For atomic write support, the WRITE ATOMIC (16) boundary is not of much
56 interest, as the block layer expects each request submitted to be executed
57 atomically. However, the SCSI spec does leave itself open to a quirky
58 scenario where MAXIMUM ATOMIC TRANSFER LENGTH is zero, yet MAXIMUM ATOMIC
59 TRANSFER LENGTH WITH BOUNDARY and MAXIMUM ATOMIC BOUNDARY SIZE are both
60 non-zero. This case will be supported.
62 To set the block layer request_queue atomic write capabilities, sanitize
63 the VPD page limits and set limits as follows:
64 - atomic_write_unit_min is derived from granularity and alignment values.
65 If no granularity value is not set, use physical block size
66 - atomic_write_unit_max is derived from MAXIMUM ATOMIC TRANSFER LENGTH. In
67 the scenario where MAXIMUM ATOMIC TRANSFER LENGTH is zero and boundary
68 limits are non-zero, use MAXIMUM ATOMIC BOUNDARY SIZE for
69 atomic_write_unit_max. New flag scsi_disk.use_atomic_write_boundary is
70 set for this scenario.
71 - atomic_write_boundary_bytes is set to zero always
73 SCSI also supports a WRITE ATOMIC (32) command, which is for type 2
74 protection enabled. This is not going to be supported now, so check for
75 T10_PI_TYPE2_PROTECTION when setting any request_queue limits.
77 To handle an atomic write request, add support for WRITE ATOMIC (16)
78 command in handler sd_setup_atomic_cmnd(). Flag use_atomic_write_boundary
79 is checked here for encoding ATOMIC BOUNDARY field.
81 Trace info is also added for WRITE_ATOMIC_16 command.
83 Upstream-Status: Backport
85 Change-Id: Ie072002fe2184615c72531ac081a324ef18cfb03
86 Signed-off-by: Kienan Stewart <kstewart@efficios.com>
87 Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
89 include/instrumentation/events/scsi.h | 98 ++++++++++++++++++++++++++-
90 1 file changed, 97 insertions(+), 1 deletion(-)
92 diff --git a/include/instrumentation/events/scsi.h b/include/instrumentation/events/scsi.h
93 index de2a1998..175ab003 100644
94 --- a/include/instrumentation/events/scsi.h
95 +++ b/include/instrumentation/events/scsi.h
98 #define scsi_opcode_name(opcode) { opcode, #opcode }
100 -#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,7,0) \
101 +#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(6,11,0))
103 +#define show_opcode_name(val) \
104 + __print_symbolic(val, \
105 + scsi_opcode_name(TEST_UNIT_READY), \
106 + scsi_opcode_name(REZERO_UNIT), \
107 + scsi_opcode_name(REQUEST_SENSE), \
108 + scsi_opcode_name(FORMAT_UNIT), \
109 + scsi_opcode_name(READ_BLOCK_LIMITS), \
110 + scsi_opcode_name(REASSIGN_BLOCKS), \
111 + scsi_opcode_name(INITIALIZE_ELEMENT_STATUS), \
112 + scsi_opcode_name(READ_6), \
113 + scsi_opcode_name(WRITE_6), \
114 + scsi_opcode_name(SEEK_6), \
115 + scsi_opcode_name(READ_REVERSE), \
116 + scsi_opcode_name(WRITE_FILEMARKS), \
117 + scsi_opcode_name(SPACE), \
118 + scsi_opcode_name(INQUIRY), \
119 + scsi_opcode_name(RECOVER_BUFFERED_DATA), \
120 + scsi_opcode_name(MODE_SELECT), \
121 + scsi_opcode_name(RESERVE), \
122 + scsi_opcode_name(RELEASE), \
123 + scsi_opcode_name(COPY), \
124 + scsi_opcode_name(ERASE), \
125 + scsi_opcode_name(MODE_SENSE), \
126 + scsi_opcode_name(START_STOP), \
127 + scsi_opcode_name(RECEIVE_DIAGNOSTIC), \
128 + scsi_opcode_name(SEND_DIAGNOSTIC), \
129 + scsi_opcode_name(ALLOW_MEDIUM_REMOVAL), \
130 + scsi_opcode_name(SET_WINDOW), \
131 + scsi_opcode_name(READ_CAPACITY), \
132 + scsi_opcode_name(READ_10), \
133 + scsi_opcode_name(WRITE_10), \
134 + scsi_opcode_name(SEEK_10), \
135 + scsi_opcode_name(POSITION_TO_ELEMENT), \
136 + scsi_opcode_name(WRITE_VERIFY), \
137 + scsi_opcode_name(VERIFY), \
138 + scsi_opcode_name(SEARCH_HIGH), \
139 + scsi_opcode_name(SEARCH_EQUAL), \
140 + scsi_opcode_name(SEARCH_LOW), \
141 + scsi_opcode_name(SET_LIMITS), \
142 + scsi_opcode_name(PRE_FETCH), \
143 + scsi_opcode_name(READ_POSITION), \
144 + scsi_opcode_name(SYNCHRONIZE_CACHE), \
145 + scsi_opcode_name(LOCK_UNLOCK_CACHE), \
146 + scsi_opcode_name(READ_DEFECT_DATA), \
147 + scsi_opcode_name(MEDIUM_SCAN), \
148 + scsi_opcode_name(COMPARE), \
149 + scsi_opcode_name(COPY_VERIFY), \
150 + scsi_opcode_name(WRITE_BUFFER), \
151 + scsi_opcode_name(READ_BUFFER), \
152 + scsi_opcode_name(UPDATE_BLOCK), \
153 + scsi_opcode_name(READ_LONG), \
154 + scsi_opcode_name(WRITE_LONG), \
155 + scsi_opcode_name(CHANGE_DEFINITION), \
156 + scsi_opcode_name(WRITE_SAME), \
157 + scsi_opcode_name(UNMAP), \
158 + scsi_opcode_name(READ_TOC), \
159 + scsi_opcode_name(LOG_SELECT), \
160 + scsi_opcode_name(LOG_SENSE), \
161 + scsi_opcode_name(XDWRITEREAD_10), \
162 + scsi_opcode_name(MODE_SELECT_10), \
163 + scsi_opcode_name(RESERVE_10), \
164 + scsi_opcode_name(RELEASE_10), \
165 + scsi_opcode_name(MODE_SENSE_10), \
166 + scsi_opcode_name(PERSISTENT_RESERVE_IN), \
167 + scsi_opcode_name(PERSISTENT_RESERVE_OUT), \
168 + scsi_opcode_name(VARIABLE_LENGTH_CMD), \
169 + scsi_opcode_name(REPORT_LUNS), \
170 + scsi_opcode_name(MAINTENANCE_IN), \
171 + scsi_opcode_name(MAINTENANCE_OUT), \
172 + scsi_opcode_name(MOVE_MEDIUM), \
173 + scsi_opcode_name(EXCHANGE_MEDIUM), \
174 + scsi_opcode_name(READ_12), \
175 + scsi_opcode_name(WRITE_12), \
176 + scsi_opcode_name(WRITE_VERIFY_12), \
177 + scsi_opcode_name(SEARCH_HIGH_12), \
178 + scsi_opcode_name(SEARCH_EQUAL_12), \
179 + scsi_opcode_name(SEARCH_LOW_12), \
180 + scsi_opcode_name(READ_ELEMENT_STATUS), \
181 + scsi_opcode_name(SEND_VOLUME_TAG), \
182 + scsi_opcode_name(WRITE_LONG_2), \
183 + scsi_opcode_name(READ_16), \
184 + scsi_opcode_name(WRITE_16), \
185 + scsi_opcode_name(VERIFY_16), \
186 + scsi_opcode_name(WRITE_SAME_16), \
187 + scsi_opcode_name(ZBC_OUT), \
188 + scsi_opcode_name(ZBC_IN), \
189 + scsi_opcode_name(SERVICE_ACTION_IN_16), \
190 + scsi_opcode_name(READ_32), \
191 + scsi_opcode_name(WRITE_32), \
192 + scsi_opcode_name(WRITE_SAME_32), \
193 + scsi_opcode_name(ATA_16), \
194 + scsi_opcode_name(WRITE_ATOMIC_16), \
195 + scsi_opcode_name(ATA_12))
197 +#elif (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,7,0) \
198 || LTTNG_SLE_KERNEL_RANGE(4,4,9,36,0,0, 4,5,0,0,0,0))
200 #define show_opcode_name(val) \