Re: [PATCH 03/18] MM: use ->swap_rw for reads from SWP_FS_OPS swap-space
From: Christoph Hellwig <hch@infradead.org>
Date: 2021-12-21 08:40:23
Also in:
linux-nfs, lkml
+int sio_pool_init(void)
+{
+ if (!sio_pool)
+ sio_pool = mempool_create_kmalloc_pool(
+ SWAP_CLUSTER_MAX, sizeof(struct swap_iocb));I can't see anything serializing access here, so we'll need a lock or cmpxchg dance.
+ if (sio_pool) + return 0; + else + return -ENOMEM;
Nit: This would flow much nicer as: if (!sio_pool) return -ENOMEM; return 0;
quoted hunk ↗ jump to hunk
int swap_readpage(struct page *page, bool synchronous) { struct bio *bio;@@ -378,13 +412,25 @@ int swap_readpage(struct page *page, bool synchronous) } if (data_race(sis->flags & SWP_FS_OPS)) { - //struct file *swap_file = sis->swap_file; - //struct address_space *mapping = swap_file->f_mapping;
This should not be left by the previous patch. In fact I suspect the part of the previous patch that adds ->swap_rw should probably be folded into this patch.
+ struct file *swap_file = sis->swap_file; + struct address_space *mapping = swap_file->f_mapping; + struct iov_iter from; + struct swap_iocb *sio; + loff_t pos = page_file_offset(page); + + sio = mempool_alloc(sio_pool, GFP_KERNEL); + init_sync_kiocb(&sio->iocb, swap_file); + sio->iocb.ki_pos = pos; + sio->iocb.ki_complete = sio_read_complete; + sio->bvec.bv_page = page; + sio->bvec.bv_len = PAGE_SIZE; + sio->bvec.bv_offset = 0; + + iov_iter_bvec(&from, READ, &sio->bvec, 1, PAGE_SIZE); + ret = mapping->a_ops->swap_rw(&sio->iocb, &from); + if (ret != -EIOCBQUEUED) + sio_read_complete(&sio->iocb, ret); goto out;
I'd be tempted to split the SWP_FS_OPS into a helper to keep the code tidy.