Re: [PATCH 13/16] block: switch polling to be bio based

Ming Lei
2021-06-21T08:36:11Z

On Mon, Jun 21, 2021 at 09:20:05AM +0200, Christoph Hellwig wrote:
> On Fri, Jun 18, 2021 at 10:27:20PM +0800, Ming Lei wrote:
> > > How? On a block device the caller needs to hold the block device open
> > > to read/write from it. On a file systems the file systems needs to
> > > be mounted, which also holds a bdev reference.
> >
> > + rcu_read_lock();
> > + bio = READ_ONCE(kiocb->private);
> > + if (bio && bio->bi_bdev)
> >
> > The bio may be ended now from another polling job, then the disk is
> > closed & deleted, and released. Then request queue & hctxs are released.
> >
> > + ret = bio_poll(bio, flags);
> >
> > But disk & request queue & hctx can still be referred in above bio_poll().
>
> I don't see how this can happen. A bio stashed into kiocb->private needs
> to belong to the correct device initially. For it to point to the "wrong"
> device it needs to have been completed on the correct one, and then be
> reused for a different device. At the point it is reused that device
> must obviously have been alive, and for it to be freed a RCU grace
> period must have been passed. And that grace period can't have started
> earlier than when iocb_bio_iopoll was called.

gendisk isn't freed after a RCU grace period, so even though bio->bi_bdev
may not be freed really, but the gendisk may have been freed already.

+ rcu_read_lock();
+ bio = READ_ONCE(kiocb->private);
+ if (bio && bio->bi_bdev)

The bio may be ended now from another polling job, and it is freed
and re-allocated & freed, then bio->bi_bdev->bd_disk is freed too, which
will be observed in the following bio_poll().

+ ret = bio_poll(bio, flags);

Thanks,
Ming