[Devel] [PATCH vz7 1/2] ploop: store exec_ub in ploop request and use it while processing requests
Andrey Ryabinin
aryabinin at virtuozzo.com
Thu Aug 2 19:36:58 MSK 2018
On 08/02/2018 05:11 PM, Konstantin Khorenko wrote:
> ploop_req_state_process() is intended to set up proper exec_ub
> while processing ploop requests, but it uses preq->ioc->ioc_ub which is
> almost always incorrect.
>
> ploop requests are created in kworker which is run in host:
>
> kworker/u16:5 319 [005] 841.012218: probe:ploop_grab_iocontext: (ffffffffc0004542)
> 45b3 ploop_make_request (/lib/modules/3.10.0/kernel/drivers/block/ploop/ploop.ko)
> 5345bb generic_make_request ([kernel.kallsyms])
> 534843 submit_bio ([kernel.kallsyms])
> 12185 ext4_io_submit ([ext4])
> 123e9 ext4_bio_write_page ([ext4])
> 82bd mpage_submit_page ([ext4])
> 8568 mpage_map_and_submit_buffers ([ext4])
> dff5 ext4_writepages ([ext4])
> 3b0221 do_writepages ([kernel.kallsyms])
> 460dba __writeback_single_inode ([kernel.kallsyms])
> 4613b5 writeback_sb_inodes ([kernel.kallsyms])
> 4617b2 __writeback_inodes_wb ([kernel.kallsyms])
> 461a43 wb_writeback ([kernel.kallsyms])
> 462376 bdi_writeback_workfn ([kernel.kallsyms])
> 2b11d5 process_one_work ([kernel.kallsyms])
> 2b237e worker_thread ([kernel.kallsyms])
> 2b9781 kthread ([kernel.kallsyms])
> 90ebf7 ret_from_fork ([kernel.kallsyms])
>
> "kworker/u16:5" has exec_ub == ub0
> and ploop_make_request() stores io_context from "current" == kworker in bio and
> sets flag BIO_BDEV_REUSED:
>
> queue:
> BUG_ON (bio->bi_bdev != plo->bdev && bio_sectors(bio));
> if (bio->bi_bdev == plo->bdev) {
> BUG_ON (test_bit(BIO_BDEV_REUSED, &bio->bi_flags));
> ploop_grab_iocontext(bio);
> }
> ==========
> static void ploop_grab_iocontext(struct bio *bio)
> {
> struct io_context **ioc_pp = (struct io_context **)(&bio->bi_bdev);
> if (current->io_context) {
> ioc_task_link(current->io_context);
> *ioc_pp = current->io_context;
> ==========
> Meanwhile ploop_thread() processes bios:
>
> ploop_thread
> process_pending_bios
> ploop_bio_queue
> get a free ploop request
> if BIO_BDEV_REUSED is set to bio, preq->ioc = saved io_context (with ub0)
>
> ploop_bio_queue(struct ploop_device * plo, struct bio * bio,
> struct list_head *drop_list, int account_blockable)
> {
> if (test_bit(BIO_BDEV_REUSED, &bio->bi_flags)) {
> preq->ioc = (struct io_context *)(bio->bi_bdev);
> bio->bi_bdev = plo->bdev;
> clear_bit(BIO_BDEV_REUSED, &bio->bi_flags);
>
> => now preq->ioc contains exec_ub == ub0
> later ploop_thread() -> ploop_req_state_process() executes
> set_exec_ub(preq->ioc->ioc_ub) // == ub0
>
> This patch adds preq::preq_ub field to "ploop_request" and sets it up properly
> on ploop request creation.
>
> Q: Why do we have proper current->exec_ub on ploop request creation time?
> A: See calltrace above - it goes through __writeback_single_inode which
> sets proper exec_ub.
>
> __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
> {
> ...
> ub = rcu_dereference(inode->i_mapping->dirtied_ub);
> ...
> ub = set_exec_ub(ub);
> ret = __do_writeback_single_inode(inode, wbc);
> put_beancounter(set_exec_ub(ub));
> ...
>
> https://jira.sw.ru/browse/PSBM-86910
>
> Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
> ---
Reviewed-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
More information about the Devel
mailing list