On Fri, Jan 13, 2023 at 11:19:17AM +0800, Baoquan He wrote: > + spin_lock(&vb->lock); > + if (bitmap_empty(vb->used_map, VMAP_BBMAP_BITS)) { > + spin_unlock(&vb->lock); > + memset(buf, 0, count); > + return; > + } > + for_each_set_bitrange(rs, re, vb->used_map, VMAP_BBMAP_BITS) { > + if (!count) > + break; > + start = vmap_block_vaddr(vb->va->va_start, rs); > + while (addr < start) { > + if (count == 0) > + break; > + *buf = '\0'; > + buf++; > + addr++; > + count--; > + } > + /*it could start reading from the middle of used region*/ > + offset = offset_in_page(addr); > + n = ((re - rs + 1) << PAGE_SHIFT) - offset; > + if (n > count) > + n = count; > + aligned_vread(buf, start+offset, n); The whole vread() interface is rather suboptimal. The only user is proc, which is trying to copy to userspace. But the vread() interface copies to a kernel address, so kcore has to copy to a bounce buffer. That makes this spinlock work, but the price is that we can't copy to a user address in the future. Ideally, read_kcore() would be kcore_read_iter() and we'd pass an iov_iter into vread(). vread() would then need to use a mutex rather than a spinlock. I don't think this needs to be done now, but if someone's looking for a project ...