Do not discard high 32 bits of length in send#1436
Do not discard high 32 bits of length in send#1436bitonic wants to merge 1 commit intoaxboe:masterfrom
Conversation
|
@axboe regarding branch or not branch: imo a predictable branch is better than a cmov (as in, it'll be cheaper in practice). But if you really care about having a cmov, I can make sure it compiles to that. |
|
I really think this should handle all the cases where this is true. And this is very much using a branch, even if it's marked unlikely. A cap function ala: would be more efficient, and that help can just be used anywhere. Also note the format of git commits for liburing. Needs a proper commit subject, commit message, identity, and signed-off-by line. |
|
Gotta run for now, I'll check back in tomorrow. |
ab895dd to
e51bc31
Compare
|
@axboe I've pushed the bit twiddly version. I've also amended all similar call sites I could find with a Should I just put the commit to be signed off by you? |
e51bc31 to
fb0508c
Compare
|
@axboe is anything holding up the merge (apart from the commit message, which I'll amend if you confirm that I should put it as signed off by you)? |
|
Sorry, OOO for a bit, back next week. Only thing holding this back is I'm still pondering if we shouldn't just document the fact that the API len is a 32-bit unsigned. I'm not really convinced that it's worth adding code to cap the transfer length. |
src/include/liburing.h
Outdated
| sqe->statx_flags = (__u32) flags; | ||
| } | ||
|
|
||
| IOURINGINLINE __u32 __io_uring_cap_len(size_t len) { |
There was a problem hiding this comment.
{ should be on the next line. Minor style issue.
There was a problem hiding this comment.
Oh and this one should just be a static inline, not IOURINGINLINE.
I think silently dropping the high 32 bits is terrible, documentation notwithstanding. Are you concerned about performance? Capping the length will be immaterial compared to the cost of the place/pickup of the SQE onto the ring anyway. |
fb0508c to
821576a
Compare
|
I think |
| __u64 offset, __u32 len, int advice) | ||
| { | ||
| io_uring_prep_rw(IORING_OP_FADVISE, sqe, fd, NULL, (__u32) len, offset); | ||
| io_uring_prep_rw(IORING_OP_FADVISE, sqe, fd, NULL, __io_uring_cap_len(len), offset); |
There was a problem hiding this comment.
len is a __u32 here, so __io_uring_cap_len is a no-op
| static inline __u32 __io_uring_cap_len(size_t len) | ||
| { | ||
| size_t mask = -(size_t)(len > UINT32_MAX); | ||
| return (len & ~mask) | (UINT32_MAX & mask); |
There was a problem hiding this comment.
Based on https://godbolt.org/z/zGeqGGMeh, I'd suggest
| return (len & ~mask) | (UINT32_MAX & mask); | |
| return len > UINT32_MAX ? UINT32_MAX : len; |
There was a problem hiding this comment.
I had this back and forth with @axboe already. I think the cmov or branching version is better than the current version too (and moreover it'll leverage max instructions for architectures that have them, like aarch64). But since @axboe has stated that he prefers the bit twiddling version I'll let him decide.
There was a problem hiding this comment.
That's not how I understood #1436 (comment) , given that it's replying to a comment that explicitly mentions cmov. But I'll let him comment.
| __u32 length, int advice) | ||
| { | ||
| io_uring_prep_rw(IORING_OP_MADVISE, sqe, -1, addr, (__u32) length, 0); | ||
| io_uring_prep_rw(IORING_OP_MADVISE, sqe, -1, addr, __io_uring_cap_len(length), 0); |
|
@axboe any news? liburing is still silently broken (both in the docs and in the types) if you do large writes. |
Fixes #1435