On 10/20/21 07:37, Christoph Hellwig wrote:
On Tue, Oct 19, 2021 at 10:24:22PM +0100, Pavel Begunkov wrote:
If we know that a iocb is async we can optimise bio_set_polled() a bit,
add a new helper bio_set_polled_async().
This avoids a single if. Why? I'm really worried about all these
micro-optimizations that just make the code harder and harder to
maintain.
Not really just one, it also moves REQ_F_NOWAIT, and alias analysis
doesn't work well here, e.g. it can't conclude anything about
relations b/w @iocb and @bio, those can do nothing but store/load
to/from memory.
Assembly related to that HIPRI path before:
# block/fops.c:378: if (iocb->ki_flags & IOCB_NOWAIT)
movl 32(%rbx), %eax # iocb_31(D)->ki_flags, _20
# block/fops.c:378: if (iocb->ki_flags & IOCB_NOWAIT)
testb $8, %al #, _20
je .L200 #,
# block/fops.c:379: bio->bi_opf |= REQ_NOWAIT;
orl $2097152, 16(%r12) #, bio_40->bi_opf
# block/fops.c:380: if (iocb->ki_flags & IOCB_HIPRI) {
movl 32(%rbx), %eax # iocb_31(D)->ki_flags, _20
.L200:
# block/fops.c:380: if (iocb->ki_flags & IOCB_HIPRI) {
testb $1, %al #, _20
je .L201 #,
# ./include/linux/bio.h:748: bio->bi_opf |= REQ_POLLED;
movl 16(%r12), %eax # bio_40->bi_opf, _73
movl %eax, %edx # _73, tmp138
orl $16777216, %edx #, tmp138
movl %edx, 16(%r12) # tmp138, bio_40->bi_opf
# ./include/linux/bio.h:749: if (!is_sync_kiocb(kiocb))
cmpq $0, 16(%rbx) #, iocb_31(D)->ki_complete
je .L202 #,
# ./include/linux/bio.h:750: bio->bi_opf |= REQ_NOWAIT;
orl $18874368, %eax #, tmp139
movl %eax, 16(%r12) # tmp139, bio_40->bi_opf
.L202:
# block/fops.c:382: submit_bio(bio);
movq %r12, %rdi # bio,
call submit_bio #
After:
# block/fops.c:378: if (iocb->ki_flags & IOCB_HIPRI) {
movl 32(%rbx), %eax # iocb_30(D)->ki_flags, _20
# block/fops.c:378: if (iocb->ki_flags & IOCB_HIPRI) {
testb $1, %al #, _20
je .L210 #,
.L213:
# ./include/linux/bio.h:755: bio->bi_opf |= REQ_POLLED | REQ_NOWAIT;
orl $18874368, 16(%r12) #, bio_39->bi_opf
# block/fops.c:380: submit_bio(bio);
movq %r12, %rdi # bio,
call submit_bio #
--
Pavel Begunkov