summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-21 14:06:19 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-21 14:06:19 -0400
commit98ea57b179df789d47505369110cfbd00ef9da6d (patch)
tree6712717dd986616ccc114e85bd9558bc82cf0502 /kernel
parent393f1c676d0fc9c7b37ab6a52efe7e2d288d7e90 (diff)
downloadopen-iov-98ea57b179df789d47505369110cfbd00ef9da6d.tar.gz
open-iov-98ea57b179df789d47505369110cfbd00ef9da6d.zip
sema: r420c 2D fills/copies with pitch == row length cover all rows
victory_memset2d failed deterministically (bad ~= 12.5M of 12.58M) because its pitched operations carry PITCH == LINE_LENGTH (cudaMallocPitch returned pitch 4096 for width 4096) and the r402 2D decode only entered row mode when a pitch was WIDER than the row. The flat path then ran ONE row (LINE_LENGTH bytes) per op, so every cudaMemcpy2D readback and H2D upload delivered only its first row and every cudaMemset2D-sized region beyond it kept stale content - the 'deterministic readback loss' (45K of 12.58M correct ~= the rows the single runs happened to cover). LINE_COUNT is now authoritative for the flat case too: pitch == row length (or no pitch method) means CONTIGUOUS rows, so the single run covers rows*line bytes (element-exact when the line divides evenly, else byte exact). A pitch wider than the row keeps the r402 row-wise mode; 1D ops are unchanged. Both the fill (cudaMemset2D/fill) and the copy (cudaMemcpy2D) decode are fixed.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c92
1 files changed, 70 insertions, 22 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index a465469..3b7c5e8 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -10000,18 +10000,45 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
* r402: a 2D fill (cudaMemset2D):
* LINE_COUNT rows of
* LINE_LENGTH_IN bytes at
- * PITCH_OUT stride. Only a pitch
- * WIDER than the row selects row
- * mode; a flat fill carries
- * pitch == row length (or no
- * pitch method) and keeps the
- * historical single-run path.
+ * PITCH_OUT stride. A pitch WIDER
+ * than the row selects row mode; a
+ * flat fill carries pitch == row
+ * length (or no pitch method) and
+ * keeps the historical single-run
+ * path.
+ *
+ * r420c: LINE_COUNT is
+ * authoritative for the flat case
+ * too - cudaMemset2D with pitch ==
+ * width (victory_memset2d,
+ * pitch=4096/w=4096) is CONTIGUOUS
+ * rows, so the single run must
+ * cover rows*line bytes. The
+ * historical path filled one row
+ * and the readback lost the rest
+ * (bad ~= 12.5M of 12.58M).
*/
- if (st.have_pitch_out &&
- st.line_count > 1 &&
- st.pitch_out > st.line_length) {
- m->rows = st.line_count;
- m->dpitch = st.pitch_out;
+ if (st.line_count > 1) {
+ u32 fpitch = st.have_pitch_out ?
+ st.pitch_out :
+ st.line_length;
+
+ if (fpitch > st.line_length) {
+ m->rows =
+ st.line_count;
+ m->dpitch = fpitch;
+ } else if (st.line_length %
+ m->elem) {
+ m->elem = 1;
+ m->count =
+ st.line_length *
+ st.line_count;
+ } else {
+ m->count =
+ (st.line_length /
+ m->elem) *
+ st.line_count;
+ }
}
if (m->rows > 1 && svc_pitch_log < 32) {
svc_pitch_log++;
@@ -10053,20 +10080,41 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
* LINE_COUNT rows of
* LINE_LENGTH_IN bytes with
* PITCH_IN/PITCH_OUT strides.
- * Row mode only when a pitch is
- * wider than the row (a flat 1D
- * copy keeps pitch == length).
+ * Row mode when a pitch is
+ * wider than the row.
+ *
+ * r420c: pitch == row length
+ * (or no pitch method) makes the
+ * rows CONTIGUOUS, so the single
+ * flat run must cover
+ * rows*line bytes - the
+ * historical path copied one row
+ * (victory_memset2d's pitched
+ * D2H/H2D at pitch 4096 = width
+ * 4096 lost all but the first
+ * row).
*/
- if (st.line_count > 1 &&
- st.have_pitch_out &&
- st.pitch_out > st.line_length) {
- m->rows = st.line_count;
- m->dpitch = st.pitch_out;
- m->spitch = st.have_pitch_in ?
+ if (st.line_count > 1) {
+ u32 dpitch = st.have_pitch_out ?
+ st.pitch_out :
+ st.line_length;
+ u32 spitch = st.have_pitch_in ?
(st.pitch_in ?
st.pitch_in :
- st.pitch_out) :
- st.pitch_out;
+ dpitch) :
+ dpitch;
+
+ if (dpitch == st.line_length &&
+ spitch == st.line_length) {
+ m->bytes =
+ st.line_length *
+ st.line_count;
+ } else {
+ m->rows =
+ st.line_count;
+ m->dpitch = dpitch;
+ m->spitch = spitch;
+ }
}
n_ops++;
ops_seq++;