On Tue, Jul 24, 2018 at 04:33:41PM +0300, Max Gurtovoy wrote: > +void t10_pi_prepare(struct request *rq, u8 protection_type) > +{ > + const int tuple_sz = rq->q->integrity.tuple_size; > + u32 ref_tag = t10_pi_ref_tag(rq); > + struct bio *bio; > + > + if (protection_type == T10_PI_TYPE3_PROTECTION) > + return; > + > + __rq_for_each_bio(bio, rq) { > + struct bio_integrity_payload *bip = bio_integrity(bio); > + u32 virt = bip_get_seed(bip) & 0xffffffff; > + struct bio_vec iv; > + struct bvec_iter iter; > + > + /* Already remapped? */ > + if (bip->bip_flags & BIP_MAPPED_INTEGRITY) > + break; > + > + bip_for_each_vec(iv, bip, iter) { > + struct t10_pi_tuple *pi = kmap_atomic(iv.bv_page) + > + iv.bv_offset; > + unsigned int j; > + > + for (j = 0; j < iv.bv_len; j += tuple_sz) { > + if (be32_to_cpu(pi->ref_tag) == virt) > + pi->ref_tag = cpu_to_be32(ref_tag); > + virt++; > + ref_tag++; > + pi += tuple_sz; > + } > + > + kunmap_atomic(pi); > + }
Since you're incrementing 'pi', you end up unmapping an address that you didn't map. It does appears harmless in current kunmap_atomic() implementation, though. You are also incrementing 'pi' by too many bytes since it is of type struct t10_pi_tuple. The nvme driver used void* to make the pointer arithmentic easier.