On 6/26/2024 10:29 AM, Christoph Hellwig wrote: > + struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); > + struct bio_integrity_payload *bip = bio_integrity(bio); > + struct blk_integrity_iter iter; > + struct bvec_iter bviter; > + struct bio_vec bv; > + > + iter.disk_name = bio->bi_bdev->bd_disk->disk_name; > + iter.interval = 1 << bi->interval_exp; > + iter.seed = bio->bi_iter.bi_sector; > + iter.prot_buf = bvec_virt(bip->bip_vec); > + bio_for_each_segment(bv, bio, bviter) { > + void *kaddr = bvec_kmap_local(&bv); > + > + iter.data_buf = kaddr; > + iter.data_size = bv.bv_len; > + switch (bi->csum_type) { > + case BLK_INTEGRITY_CSUM_CRC64: > + ext_pi_crc64_generate(&iter, bi); > + break; > + case BLK_INTEGRITY_CSUM_CRC: > + case BLK_INTEGRITY_CSUM_IP: > + t10_pi_generate(&iter, bi); > + break; > + default: > + break; > + } The bi->csum_type is constant as far as this bio_for_each_segment loop is concerned. Seems wasteful processing, and can rather be moved out where we set a function pointer to point to either ext_pi_crc64_generate or t10_pi_generate once.