Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wait_for_completion for submit_bio in make_request not returning

I am writing a custom block driver in the Linux kernel and in my make_request routine, on writes I need to read the data of the bio's specified sector (from the physical drive) prior to writing the new data. My excerpt below showcases most of what I am trying to accomplish but for whatever reason, I never get a return from the wait_for_completion. Once I/O is executed to the block device. It hangs after the submit_bio and never continues. Every 120 seconds I get a stack dump and message saying how the task is blocked. Any ideas? Thoughts?

... in make_request ....

if(rw != READ){
    struct completion event;
    struct bio *biow = bio_alloc(GFP_NOIO, bio_segments(bio));
    biow->bi_bdev = bio->bi_bdev;
    biow->bi_sector = bio->sector;
    biow->bi_rw = READ_SYNC;
    biow->bi_vcnt = bio_segments(bio);
    biow->bi_size = bio->bi_size;
    init_completion(&event);
    biow->bi_private = &event;
    biow->bi_end_io = bi_complete;
    submit_bio(READ_SYNC, biow);
    wait_for_completion(&event);
    .... some more magic occurs here ....
}
generic_make_request(bio);

like image 703
pkoutoupis Avatar asked Nov 23 '22 18:11

pkoutoupis


1 Answers

Maybe you can create a kernel thread, and do reading/writing ops in the thread. Really, I don't know why it works, I refer to relevant examples and try to do it, and find that it works.

To explain more clearly, I write the example as below:

static void trigger_some_event()
{
     struct task_struct *task;
     task = kthread_create(<your_func>, <arg>, "<desc>");
     if(task){
         wake_up_process(task);
     }
}
like image 104
Aliez Avatar answered Dec 05 '22 10:12

Aliez