This moves unaligned/hybrid IO to using page pools. This
reduces the time spent in memory allocation while doing IO
to near zero, at least in simple tests.
This should close most of the performance gap between
udio/hybrid and regular DIO for reads, taking them from
~13 GiB/s to close to 20 GiB/s. This should also scale as
DIO performance improves.
The improvement for writes is much more limited, because
UDIO writes do not have parallel data copy yet. This will
improve UDIO write performance by perhaps 10-20%, so from
~2.5 GiB/s to ~3.0 GiB/s, very roughly.
Signed-off-by: Patrick Farrell <patrick.farrell@oracle.com>
Change-Id: I0cb8b5881bf2885a926383291f67fa252b56574f
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53670
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
*/
int ll_allocate_dio_buffer(struct ll_dio_pages *pvec, size_t io_size)
{
*/
int ll_allocate_dio_buffer(struct ll_dio_pages *pvec, size_t io_size)
{
size_t pg_offset;
int result = 0;
size_t pg_offset;
int result = 0;
OBD_ALLOC_PTR_ARRAY_LARGE(pvec->ldp_pages, pvec->ldp_count);
#endif
if (pvec->ldp_pages == NULL)
OBD_ALLOC_PTR_ARRAY_LARGE(pvec->ldp_pages, pvec->ldp_count);
#endif
if (pvec->ldp_pages == NULL)
- RETURN(-ENOMEM);
-
- for (i = 0; i < pvec->ldp_count; i++) {
- new_page = alloc_page(GFP_NOFS);
- if (!new_page) {
- result = -ENOMEM;
- pvec->ldp_count = i;
- goto out;
- }
- pvec->ldp_pages[i] = new_page;
- }
- WARN_ON(i != pvec->ldp_count);
+ GOTO(out, result = -ENOMEM);
+
+ result = obd_pool_get_pages_array(pvec->ldp_pages, pvec->ldp_count);
+ if (result)
+ GOTO(out, result);
void ll_free_dio_buffer(struct ll_dio_pages *pvec)
{
void ll_free_dio_buffer(struct ll_dio_pages *pvec)
{
- int i;
-
- for (i = 0; i < pvec->ldp_count; i++)
- __free_page(pvec->ldp_pages[i]);
+ obd_pool_put_pages_array(pvec->ldp_pages, pvec->ldp_count);
- kfree(pvec->ldp_pages);
+ kvfree(pvec->ldp_pages);
#else
OBD_FREE_PTR_ARRAY_LARGE(pvec->ldp_pages, pvec->ldp_count);
#endif
#else
OBD_FREE_PTR_ARRAY_LARGE(pvec->ldp_pages, pvec->ldp_count);
#endif