Hi Ming,
On 2019/06/27 16:47, Ming Lei wrote:
[...]
>> static void bio_copy_kern_endio_read(struct bio *bio)
>> {
>> + unsigned long len = 0;
>> char *p = bio->bi_private;
>> struct bio_vec *bvec;
>> struct bvec_iter_all iter_all;
>> @@ -1550,8 +1583,12 @@ static void bio_copy_kern_endio_read(struct bio *bio)
>> bio_for_each_segment_all(bvec, bio, iter_all) {
>> memcpy(p, page_address(bvec->bv_page), bvec->bv_len);
>> p += bvec->bv_len;
>> + len += bvec->bv_len;
>> }
>>
>> + if (is_vmalloc_addr(bio->bi_private))
>> + invalidate_kernel_vmap_range(bio->bi_private, len);
>> +
>> bio_copy_kern_endio(bio);
>> }
>>
>> @@ -1572,6 +1609,7 @@ struct bio *bio_copy_kern(struct request_queue *q,
>> void *data, unsigned int len,
>> unsigned long kaddr = (unsigned long)data;
>> unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
>> unsigned long start = kaddr >> PAGE_SHIFT;
>> + bool is_vmalloc = is_vmalloc_addr(data);
>> struct bio *bio;
>> void *p = data;
>> int nr_pages = 0;
>> @@ -1587,6 +1625,9 @@ struct bio *bio_copy_kern(struct request_queue *q,
>> void *data, unsigned int len,
>> if (!bio)
>> return ERR_PTR(-ENOMEM);
>>
>> + if (is_vmalloc)
>> + flush_kernel_vmap_range(data, len);
>> +
>
> Are your sure that invalidate[|flush]_kernel_vmap_range is needed for
> bio_copy_kernel? The vmalloc buffer isn't involved in IO, and only
> accessed by CPU.
Not sure at all. I am a little out of my league here.
Christoph mentioned that this is necessary.
Christoph, can you confirm ?
Thanks !
--
Damien Le Moal
Western Digital Research