<div dir="ltr"><div><div><br>mm/page_io.c<br><br>static struct bio *get_swap_bio(gfp_t gfp_flags,<br>                                struct page *page, bio_end_io_t end_io)<br>{<br>        bio = bio_alloc(gfp_flags, 1);<br>        if (bio) {<br>                bio-&gt;bi_iter.bi_sector = map_swap_page(page, &amp;bio-&gt;bi_bdev);<br>                bio-&gt;bi_iter.bi_sector &lt;&lt;= PAGE_SHIFT - 9;<br>                bio-&gt;bi_iter.bi_size = PAGE_SIZE;<br>                bio-&gt;bi_end_io = end_io;<br>        }<br>        return bio;<br>}<br><br><br>bi_endio() calls bio-&gt;bi_end_io. One should assign a routine to bio-&gt;bi_end_io.<br>One can wake up the thread waiting for IO in bi_end_io. For example: direct IO<br>has assigned dio_bio_end_io routine to bio-&gt;bi_end_io<br><br>fs/direct-io.c<br><br>/*<br> * The BIO completion handler simply queues the BIO up for the process-context<br> * handler.<br> *<br> * During I/O bi_private points at the dio.  After I/O, bi_private is used to<br> * implement a singly-linked list of completed BIOs, at dio-&gt;bio_list.<br> */<br>static void dio_bio_end_io(struct bio *bio, int error)<br>{<br>        struct dio *dio = bio-&gt;bi_private;<br>        <br>        bio-&gt;bi_private = dio-&gt;bio_list;<br>        dio-&gt;bio_list = bio;<br>        if (--dio-&gt;refcount == 1 &amp;&amp; dio-&gt;waiter)<br>                wake_up_process(dio-&gt;waiter);<br>}<br><br><br></div>Regards<br></div>Manoj Nayak<br></div>