| .. | .. |
|---|
| 67 | 67 | struct crypt_config *cc; |
|---|
| 68 | 68 | struct bio *base_bio; |
|---|
| 69 | 69 | u8 *integrity_metadata; |
|---|
| 70 | | - bool integrity_metadata_from_pool; |
|---|
| 70 | + bool integrity_metadata_from_pool:1; |
|---|
| 71 | + bool in_tasklet:1; |
|---|
| 72 | + |
|---|
| 71 | 73 | struct work_struct work; |
|---|
| 72 | 74 | struct tasklet_struct tasklet; |
|---|
| 73 | 75 | |
|---|
| .. | .. |
|---|
| 1722 | 1724 | io->ctx.r.req = NULL; |
|---|
| 1723 | 1725 | io->integrity_metadata = NULL; |
|---|
| 1724 | 1726 | io->integrity_metadata_from_pool = false; |
|---|
| 1727 | + io->in_tasklet = false; |
|---|
| 1725 | 1728 | atomic_set(&io->io_pending, 0); |
|---|
| 1726 | 1729 | } |
|---|
| 1727 | 1730 | |
|---|
| .. | .. |
|---|
| 1767 | 1770 | * our tasklet. In this case we need to delay bio_endio() |
|---|
| 1768 | 1771 | * execution to after the tasklet is done and dequeued. |
|---|
| 1769 | 1772 | */ |
|---|
| 1770 | | - if (tasklet_trylock(&io->tasklet)) { |
|---|
| 1771 | | - tasklet_unlock(&io->tasklet); |
|---|
| 1772 | | - bio_endio(base_bio); |
|---|
| 1773 | + if (io->in_tasklet) { |
|---|
| 1774 | + INIT_WORK(&io->work, kcryptd_io_bio_endio); |
|---|
| 1775 | + queue_work(cc->io_queue, &io->work); |
|---|
| 1773 | 1776 | return; |
|---|
| 1774 | 1777 | } |
|---|
| 1775 | 1778 | |
|---|
| 1776 | | - INIT_WORK(&io->work, kcryptd_io_bio_endio); |
|---|
| 1777 | | - queue_work(cc->io_queue, &io->work); |
|---|
| 1779 | + bio_endio(base_bio); |
|---|
| 1778 | 1780 | } |
|---|
| 1779 | 1781 | |
|---|
| 1780 | 1782 | /* |
|---|
| .. | .. |
|---|
| 1934 | 1936 | io = crypt_io_from_node(rb_first(&write_tree)); |
|---|
| 1935 | 1937 | rb_erase(&io->rb_node, &write_tree); |
|---|
| 1936 | 1938 | kcryptd_io_write(io); |
|---|
| 1939 | + cond_resched(); |
|---|
| 1937 | 1940 | } while (!RB_EMPTY_ROOT(&write_tree)); |
|---|
| 1938 | 1941 | blk_finish_plug(&plug); |
|---|
| 1939 | 1942 | } |
|---|
| .. | .. |
|---|
| 2227 | 2230 | * it is being executed with irqs disabled. |
|---|
| 2228 | 2231 | */ |
|---|
| 2229 | 2232 | if (in_irq() || irqs_disabled()) { |
|---|
| 2233 | + io->in_tasklet = true; |
|---|
| 2230 | 2234 | tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work); |
|---|
| 2231 | 2235 | tasklet_schedule(&io->tasklet); |
|---|
| 2232 | 2236 | return; |
|---|