Skip to content

Commit 01a2896

Browse files
yhrcmaiolino
authored andcommitted
xfs: always allocate the free zone with the lowest index
Zones in the beginning of the address space are typically mapped to higer bandwidth tracks on HDDs than those at the end of the address space. So, in stead of allocating zones "round robin" across the whole address space, always allocate the zone with the lowest index. This increases average write bandwidth for overwrite workloads when less than the full capacity is being used. At ~50% utilization this improves bandwidth for a random file overwrite benchmark with 128MiB files and 256MiB zone capacity by 30%. Running the same benchmark with small 2-8 MiB files at 67% capacity shows no significant difference in performance. Due to heavy fragmentation the whole zone range is in use, greatly limiting the number of free zones with high bw. Signed-off-by: Hans Holmberg <hans.holmberg@wdc.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
1 parent 4d6d335 commit 01a2896

2 files changed

Lines changed: 17 additions & 31 deletions

File tree

fs/xfs/xfs_zone_alloc.c

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -408,31 +408,6 @@ xfs_zone_free_blocks(
408408
return 0;
409409
}
410410

411-
static struct xfs_group *
412-
xfs_find_free_zone(
413-
struct xfs_mount *mp,
414-
unsigned long start,
415-
unsigned long end)
416-
{
417-
struct xfs_zone_info *zi = mp->m_zone_info;
418-
XA_STATE (xas, &mp->m_groups[XG_TYPE_RTG].xa, start);
419-
struct xfs_group *xg;
420-
421-
xas_lock(&xas);
422-
xas_for_each_marked(&xas, xg, end, XFS_RTG_FREE)
423-
if (atomic_inc_not_zero(&xg->xg_active_ref))
424-
goto found;
425-
xas_unlock(&xas);
426-
return NULL;
427-
428-
found:
429-
xas_clear_mark(&xas, XFS_RTG_FREE);
430-
atomic_dec(&zi->zi_nr_free_zones);
431-
zi->zi_free_zone_cursor = xg->xg_gno;
432-
xas_unlock(&xas);
433-
return xg;
434-
}
435-
436411
static struct xfs_open_zone *
437412
xfs_init_open_zone(
438413
struct xfs_rtgroup *rtg,
@@ -472,13 +447,25 @@ xfs_open_zone(
472447
bool is_gc)
473448
{
474449
struct xfs_zone_info *zi = mp->m_zone_info;
450+
XA_STATE (xas, &mp->m_groups[XG_TYPE_RTG].xa, 0);
475451
struct xfs_group *xg;
476452

477-
xg = xfs_find_free_zone(mp, zi->zi_free_zone_cursor, ULONG_MAX);
478-
if (!xg)
479-
xg = xfs_find_free_zone(mp, 0, zi->zi_free_zone_cursor);
480-
if (!xg)
481-
return NULL;
453+
/*
454+
* Pick the free zone with lowest index. Zones in the beginning of the
455+
* address space typically provides higher bandwidth than those at the
456+
* end of the address space on HDDs.
457+
*/
458+
xas_lock(&xas);
459+
xas_for_each_marked(&xas, xg, ULONG_MAX, XFS_RTG_FREE)
460+
if (atomic_inc_not_zero(&xg->xg_active_ref))
461+
goto found;
462+
xas_unlock(&xas);
463+
return NULL;
464+
465+
found:
466+
xas_clear_mark(&xas, XFS_RTG_FREE);
467+
atomic_dec(&zi->zi_nr_free_zones);
468+
xas_unlock(&xas);
482469

483470
set_current_state(TASK_RUNNING);
484471
return xfs_init_open_zone(to_rtg(xg), 0, write_hint, is_gc);

fs/xfs/xfs_zone_priv.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ struct xfs_zone_info {
7272
/*
7373
* Free zone search cursor and number of free zones:
7474
*/
75-
unsigned long zi_free_zone_cursor;
7675
atomic_t zi_nr_free_zones;
7776

7877
/*

0 commit comments

Comments
 (0)