[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