Lines Matching +full:temperature +full:- +full:tracking
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2023-2025 Christoph Hellwig.
4 * Copyright (c) 2024-2025, Western Digital Corporation or its affiliates.
35 xfs_rtgroup_rele(oz->oz_rtg); in xfs_open_zone_free_rcu()
43 if (atomic_dec_and_test(&oz->oz_ref)) in xfs_open_zone_put()
44 call_rcu(&oz->oz_rcu, xfs_open_zone_free_rcu); in xfs_open_zone_put()
53 mp->m_groups[XG_TYPE_RTG].blocks; in xfs_zone_bucket()
62 __set_bit(rgno, zi->zi_used_bucket_bitmap[to_bucket]); in xfs_zone_add_to_bucket()
63 zi->zi_used_bucket_entries[to_bucket]++; in xfs_zone_add_to_bucket()
72 __clear_bit(rgno, zi->zi_used_bucket_bitmap[from_bucket]); in xfs_zone_remove_from_bucket()
73 zi->zi_used_bucket_entries[from_bucket]--; in xfs_zone_remove_from_bucket()
81 struct xfs_group *xg = &rtg->rtg_group; in xfs_zone_account_reclaimable()
83 struct xfs_zone_info *zi = mp->m_zone_info; in xfs_zone_account_reclaimable()
84 uint32_t used = rtg_rmap(rtg)->i_used_blocks; in xfs_zone_account_reclaimable()
106 spin_lock(&zi->zi_used_buckets_lock); in xfs_zone_account_reclaimable()
109 spin_unlock(&zi->zi_used_buckets_lock); in xfs_zone_account_reclaimable()
111 spin_lock(&zi->zi_reset_list_lock); in xfs_zone_account_reclaimable()
112 xg->xg_next_reset = zi->zi_reset_list; in xfs_zone_account_reclaimable()
113 zi->zi_reset_list = xg; in xfs_zone_account_reclaimable()
114 spin_unlock(&zi->zi_reset_list_lock); in xfs_zone_account_reclaimable()
116 if (zi->zi_gc_thread) in xfs_zone_account_reclaimable()
117 wake_up_process(zi->zi_gc_thread); in xfs_zone_account_reclaimable()
123 spin_lock(&zi->zi_used_buckets_lock); in xfs_zone_account_reclaimable()
125 spin_unlock(&zi->zi_used_buckets_lock); in xfs_zone_account_reclaimable()
127 if (zi->zi_gc_thread && xfs_zoned_need_gc(mp)) in xfs_zone_account_reclaimable()
128 wake_up_process(zi->zi_gc_thread); in xfs_zone_account_reclaimable()
134 spin_lock(&zi->zi_used_buckets_lock); in xfs_zone_account_reclaimable()
137 spin_unlock(&zi->zi_used_buckets_lock); in xfs_zone_account_reclaimable()
151 spin_lock(&zi->zi_used_buckets_lock); in xfs_zoned_have_reclaimable()
153 if (zi->zi_used_bucket_entries[i]) { in xfs_zoned_have_reclaimable()
154 spin_unlock(&zi->zi_used_buckets_lock); in xfs_zoned_have_reclaimable()
158 spin_unlock(&zi->zi_used_buckets_lock); in xfs_zoned_have_reclaimable()
167 struct xfs_rtgroup *rtg = oz->oz_rtg; in xfs_open_zone_mark_full()
169 struct xfs_zone_info *zi = mp->m_zone_info; in xfs_open_zone_mark_full()
170 uint32_t used = rtg_rmap(rtg)->i_used_blocks; in xfs_open_zone_mark_full()
174 WRITE_ONCE(rtg->rtg_open_zone, NULL); in xfs_open_zone_mark_full()
176 spin_lock(&zi->zi_open_zones_lock); in xfs_open_zone_mark_full()
177 if (oz->oz_is_gc) { in xfs_open_zone_mark_full()
178 ASSERT(current == zi->zi_gc_thread); in xfs_open_zone_mark_full()
179 zi->zi_open_gc_zone = NULL; in xfs_open_zone_mark_full()
181 zi->zi_nr_open_zones--; in xfs_open_zone_mark_full()
182 list_del_init(&oz->oz_entry); in xfs_open_zone_mark_full()
184 spin_unlock(&zi->zi_open_zones_lock); in xfs_open_zone_mark_full()
187 wake_up_all(&zi->zi_zone_wait); in xfs_open_zone_mark_full()
189 xfs_zone_account_reclaimable(rtg, rtg_blocks(rtg) - used); in xfs_open_zone_mark_full()
199 struct xfs_mount *mp = tp->t_mountp; in xfs_zone_record_blocks()
200 struct xfs_rtgroup *rtg = oz->oz_rtg; in xfs_zone_record_blocks()
207 rmapip->i_used_blocks += len; in xfs_zone_record_blocks()
208 ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg)); in xfs_zone_record_blocks()
209 oz->oz_written += len; in xfs_zone_record_blocks()
210 if (oz->oz_written == rtg_blocks(rtg)) in xfs_zone_record_blocks()
225 struct xfs_rtgroup *rtg = oz->oz_rtg; in xfs_zone_skip_blocks()
230 oz->oz_written += len; in xfs_zone_skip_blocks()
231 if (oz->oz_written == rtg_blocks(rtg)) in xfs_zone_skip_blocks()
251 error = xfs_bmapi_read(ip, new->br_startoff, new->br_blockcount, &data, in xfs_zoned_map_extent()
260 ASSERT(new->br_blockcount >= data.br_blockcount); in xfs_zoned_map_extent()
261 new->br_blockcount = data.br_blockcount; in xfs_zoned_map_extent()
305 xfs_zone_record_blocks(tp, oz, new->br_startblock, new->br_blockcount); in xfs_zoned_map_extent()
313 xfs_zone_skip_blocks(oz, new->br_blockcount); in xfs_zoned_map_extent()
326 struct xfs_mount *mp = ip->i_mount; in xfs_zoned_end_io()
339 return -EIO; in xfs_zoned_end_io()
342 new.br_blockcount = end_fsb - new.br_startoff; in xfs_zoned_end_io()
344 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, in xfs_zoned_end_io()
381 struct xfs_mount *mp = tp->t_mountp; in xfs_zone_free_blocks()
386 if (len > rmapip->i_used_blocks) { in xfs_zone_free_blocks()
389 len, rmapip->i_used_blocks); in xfs_zone_free_blocks()
390 ASSERT(len <= rmapip->i_used_blocks); in xfs_zone_free_blocks()
393 return -EFSCORRUPTED; in xfs_zone_free_blocks()
398 rmapip->i_used_blocks -= len; in xfs_zone_free_blocks()
404 if (!READ_ONCE(rtg->rtg_open_zone)) in xfs_zone_free_blocks()
417 struct xfs_zone_info *zi = mp->m_zone_info; in xfs_find_free_zone()
418 XA_STATE (xas, &mp->m_groups[XG_TYPE_RTG].xa, start); in xfs_find_free_zone()
423 if (atomic_inc_not_zero(&xg->xg_active_ref)) in xfs_find_free_zone()
430 atomic_dec(&zi->zi_nr_free_zones); in xfs_find_free_zone()
431 zi->zi_free_zone_cursor = xg->xg_gno; in xfs_find_free_zone()
446 spin_lock_init(&oz->oz_alloc_lock); in xfs_init_open_zone()
447 atomic_set(&oz->oz_ref, 1); in xfs_init_open_zone()
448 oz->oz_rtg = rtg; in xfs_init_open_zone()
449 oz->oz_allocated = write_pointer; in xfs_init_open_zone()
450 oz->oz_written = write_pointer; in xfs_init_open_zone()
451 oz->oz_write_hint = write_hint; in xfs_init_open_zone()
452 oz->oz_is_gc = is_gc; in xfs_init_open_zone()
455 * All dereferences of rtg->rtg_open_zone hold the ILOCK for the rmap in xfs_init_open_zone()
461 WRITE_ONCE(rtg->rtg_open_zone, oz); in xfs_init_open_zone()
474 struct xfs_zone_info *zi = mp->m_zone_info; in xfs_open_zone()
477 xg = xfs_find_free_zone(mp, zi->zi_free_zone_cursor, ULONG_MAX); in xfs_open_zone()
479 xg = xfs_find_free_zone(mp, 0, zi->zi_free_zone_cursor); in xfs_open_zone()
492 struct xfs_zone_info *zi = mp->m_zone_info; in xfs_try_open_zone()
495 if (zi->zi_nr_open_zones >= mp->m_max_open_zones - XFS_OPEN_GC_ZONES) in xfs_try_open_zone()
497 if (atomic_read(&zi->zi_nr_free_zones) < in xfs_try_open_zone()
498 XFS_GC_ZONES - XFS_OPEN_GC_ZONES) in xfs_try_open_zone()
505 zi->zi_nr_open_zones++; in xfs_try_open_zone()
506 spin_unlock(&zi->zi_open_zones_lock); in xfs_try_open_zone()
508 spin_lock(&zi->zi_open_zones_lock); in xfs_try_open_zone()
510 zi->zi_nr_open_zones--; in xfs_try_open_zone()
514 atomic_inc(&oz->oz_ref); in xfs_try_open_zone()
515 list_add_tail(&oz->oz_entry, &zi->zi_open_zones); in xfs_try_open_zone()
521 wake_up_all(&zi->zi_zone_wait); in xfs_try_open_zone()
524 wake_up_process(zi->zi_gc_thread); in xfs_try_open_zone()
526 trace_xfs_zone_opened(oz->oz_rtg); in xfs_try_open_zone()
542 * Life time hint co-location matrix. Fields not set default to 0
576 if (oz->oz_allocated == rtg_blocks(oz->oz_rtg)) in xfs_try_use_zone()
579 if (xfs_zoned_hint_score[oz->oz_write_hint][file_hint] < goodness) in xfs_try_use_zone()
582 if (!atomic_inc_not_zero(&oz->oz_ref)) in xfs_try_use_zone()
588 * the temperature after that as that would make little sense without in xfs_try_use_zone()
589 * tracking per-temperature class written block counts, which is in xfs_try_use_zone()
593 oz->oz_write_hint == WRITE_LIFE_NOT_SET) in xfs_try_use_zone()
594 oz->oz_write_hint = file_hint; in xfs_try_use_zone()
603 if (!list_is_last(&oz->oz_entry, &zi->zi_open_zones)) in xfs_try_use_zone()
604 list_move_tail(&oz->oz_entry, &zi->zi_open_zones); in xfs_try_use_zone()
616 lockdep_assert_held(&zi->zi_open_zones_lock); in xfs_select_open_zone_lru()
618 list_for_each_entry(oz, &zi->zi_open_zones, oz_entry) in xfs_select_open_zone_lru()
622 cond_resched_lock(&zi->zi_open_zones_lock); in xfs_select_open_zone_lru()
633 lockdep_assert_held(&zi->zi_open_zones_lock); in xfs_select_open_zone_mru()
635 list_for_each_entry_reverse(oz, &zi->zi_open_zones, oz_entry) in xfs_select_open_zone_mru()
639 cond_resched_lock(&zi->zi_open_zones_lock); in xfs_select_open_zone_mru()
645 if (xfs_has_nolifetime(ip->i_mount)) in xfs_inode_write_hint()
647 return VFS_I(ip)->i_write_hint; in xfs_inode_write_hint()
659 struct xfs_mount *mp = ip->i_mount; in xfs_zoned_pack_tight()
661 XFS_FSB_TO_B(mp, mp->m_groups[XG_TYPE_RTG].blocks); in xfs_zoned_pack_tight()
671 !(ip->i_diflags & XFS_DIFLAG_APPEND); in xfs_zoned_pack_tight()
680 struct xfs_zone_info *zi = mp->m_zone_info; in xfs_select_zone_nowait()
687 * Try to fill up open zones with matching temperature if available. It in xfs_select_zone_nowait()
688 * is better to try to co-locate data when this is favorable, so we can in xfs_select_zone_nowait()
692 spin_lock(&zi->zi_open_zones_lock); in xfs_select_zone_nowait()
722 spin_unlock(&zi->zi_open_zones_lock); in xfs_select_zone_nowait()
732 struct xfs_zone_info *zi = mp->m_zone_info; in xfs_select_zone()
741 prepare_to_wait(&zi->zi_zone_wait, &wait, TASK_UNINTERRUPTIBLE); in xfs_select_zone()
747 finish_wait(&zi->zi_zone_wait, &wait); in xfs_select_zone()
758 struct xfs_rtgroup *rtg = oz->oz_rtg; in xfs_zone_alloc_blocks()
762 spin_lock(&oz->oz_alloc_lock); in xfs_zone_alloc_blocks()
764 (xfs_filblks_t)rtg_blocks(rtg) - oz->oz_allocated); in xfs_zone_alloc_blocks()
766 spin_unlock(&oz->oz_alloc_lock); in xfs_zone_alloc_blocks()
769 allocated = oz->oz_allocated; in xfs_zone_alloc_blocks()
770 oz->oz_allocated += count_fsb; in xfs_zone_alloc_blocks()
771 spin_unlock(&oz->oz_alloc_lock); in xfs_zone_alloc_blocks()
775 *sector = xfs_gbno_to_daddr(&rtg->rtg_group, 0); in xfs_zone_alloc_blocks()
776 *is_seq = bdev_zone_is_seq(mp->m_rtdev_targp->bt_bdev, *sector); in xfs_zone_alloc_blocks()
786 struct xfs_mount *mp = XFS_I(ioend->io_inode)->i_mount; in xfs_mark_rtg_boundary()
787 sector_t sector = ioend->io_bio.bi_iter.bi_sector; in xfs_mark_rtg_boundary()
790 ioend->io_flags |= IOMAP_IOEND_BOUNDARY; in xfs_mark_rtg_boundary()
804 oz = VFS_I(ip)->i_private; in xfs_get_cached_zone()
810 ASSERT(!oz->oz_is_gc); in xfs_get_cached_zone()
811 if (!atomic_inc_not_zero(&oz->oz_ref)) in xfs_get_cached_zone()
838 atomic_inc(&oz->oz_ref); in xfs_set_cached_zone()
839 old_oz = xchg(&VFS_I(ip)->i_private, oz); in xfs_set_cached_zone()
850 ioend->io_bio.bi_iter.bi_sector = ioend->io_sector; in xfs_submit_zoned_bio()
851 ioend->io_private = oz; in xfs_submit_zoned_bio()
852 atomic_inc(&oz->oz_ref); /* for xfs_zoned_end_io */ in xfs_submit_zoned_bio()
855 ioend->io_bio.bi_opf &= ~REQ_OP_WRITE; in xfs_submit_zoned_bio()
856 ioend->io_bio.bi_opf |= REQ_OP_ZONE_APPEND; in xfs_submit_zoned_bio()
861 submit_bio(&ioend->io_bio); in xfs_submit_zoned_bio()
869 struct xfs_inode *ip = XFS_I(ioend->io_inode); in xfs_zone_alloc_and_submit()
870 struct xfs_mount *mp = ip->i_mount; in xfs_zone_alloc_and_submit()
895 alloc_len = xfs_zone_alloc_blocks(*oz, XFS_B_TO_FSB(mp, ioend->io_size), in xfs_zone_alloc_and_submit()
896 &ioend->io_sector, &is_seq); in xfs_zone_alloc_and_submit()
905 alloc_len -= split->io_bio.bi_iter.bi_size; in xfs_zone_alloc_and_submit()
917 ioend->io_bio.bi_status = errno_to_blk_status(PTR_ERR(split)); in xfs_zone_alloc_and_submit()
919 bio_io_error(&ioend->io_bio); in xfs_zone_alloc_and_submit()
936 if ((mp->m_super->s_flags & SB_ACTIVE) && mp->m_zone_info) in xfs_zoned_wake_all()
937 wake_up_all(&mp->m_zone_info->zi_zone_wait); in xfs_zoned_wake_all()
949 lockdep_assert_held(&rtg_rmap(rtg)->i_lock); in xfs_zone_rgbno_is_valid()
951 if (rtg->rtg_open_zone) in xfs_zone_rgbno_is_valid()
952 return rgbno < rtg->rtg_open_zone->oz_allocated; in xfs_zone_rgbno_is_valid()
953 return !xa_get_mark(&rtg_mount(rtg)->m_groups[XG_TYPE_RTG].xa, in xfs_zone_rgbno_is_valid()
963 spin_lock(&zi->zi_open_zones_lock); in xfs_free_open_zones()
964 while ((oz = list_first_entry_or_null(&zi->zi_open_zones, in xfs_free_open_zones()
966 list_del(&oz->oz_entry); in xfs_free_open_zones()
969 spin_unlock(&zi->zi_open_zones_lock); in xfs_free_open_zones()
991 struct xfs_zone_info *zi = mp->m_zone_info; in xfs_init_zone()
992 uint32_t used = rtg_rmap(rtg)->i_used_blocks; in xfs_init_zone()
997 return -EFSCORRUPTED; in xfs_init_zone()
1011 if (!zone || zone->cond == BLK_ZONE_COND_NOT_WP) { in xfs_init_zone()
1035 atomic_inc(&zi->zi_nr_free_zones); in xfs_init_zone()
1036 xfs_group_set_mark(&rtg->rtg_group, XFS_RTG_FREE); in xfs_init_zone()
1037 iz->available += rtg_blocks(rtg); in xfs_init_zone()
1042 atomic_inc(&rtg_group(rtg)->xg_active_ref); in xfs_init_zone()
1045 list_add_tail(&oz->oz_entry, &zi->zi_open_zones); in xfs_init_zone()
1046 zi->zi_nr_open_zones++; in xfs_init_zone()
1048 iz->available += (rtg_blocks(rtg) - write_pointer); in xfs_init_zone()
1049 iz->reclaimable += write_pointer - used; in xfs_init_zone()
1052 xfs_zone_account_reclaimable(rtg, rtg_blocks(rtg) - used); in xfs_init_zone()
1053 iz->reclaimable += (rtg_blocks(rtg) - used); in xfs_init_zone()
1066 struct xfs_mount *mp = iz->mp; in xfs_get_zone_info_cb()
1067 xfs_fsblock_t zsbno = xfs_daddr_to_rtb(mp, zone->start); in xfs_get_zone_info_cb()
1074 return -EFSCORRUPTED; in xfs_get_zone_info_cb()
1081 return -EFSCORRUPTED; in xfs_get_zone_info_cb()
1103 max_open_data_zones = (mp->m_sb.sb_rgcount - XFS_MIN_ZONES) / 2 + 1; in xfs_max_open_zones()
1111 max_open = min(max_open, mp->m_sb.sb_rgcount / 4); in xfs_max_open_zones()
1134 struct block_device *bdev = mp->m_rtdev_targp->bt_bdev; in xfs_calc_open_zones()
1137 if (!mp->m_max_open_zones) { in xfs_calc_open_zones()
1139 mp->m_max_open_zones = bdev_open_zones; in xfs_calc_open_zones()
1141 mp->m_max_open_zones = XFS_DEFAULT_MAX_OPEN_ZONES; in xfs_calc_open_zones()
1144 if (mp->m_max_open_zones < XFS_MIN_OPEN_ZONES) { in xfs_calc_open_zones()
1147 return -EIO; in xfs_calc_open_zones()
1150 if (bdev_open_zones && bdev_open_zones < mp->m_max_open_zones) { in xfs_calc_open_zones()
1151 mp->m_max_open_zones = bdev_open_zones; in xfs_calc_open_zones()
1156 if (mp->m_max_open_zones > xfs_max_open_zones(mp)) { in xfs_calc_open_zones()
1157 mp->m_max_open_zones = xfs_max_open_zones(mp); in xfs_calc_open_zones()
1160 mp->m_max_open_zones, mp->m_sb.sb_rgcount); in xfs_calc_open_zones()
1170 return kvmalloc_array(BITS_TO_LONGS(mp->m_sb.sb_rgcount), in xfs_alloc_bucket_bitmap()
1184 INIT_LIST_HEAD(&zi->zi_open_zones); in xfs_alloc_zone_info()
1185 INIT_LIST_HEAD(&zi->zi_reclaim_reservations); in xfs_alloc_zone_info()
1186 spin_lock_init(&zi->zi_reset_list_lock); in xfs_alloc_zone_info()
1187 spin_lock_init(&zi->zi_open_zones_lock); in xfs_alloc_zone_info()
1188 spin_lock_init(&zi->zi_reservation_lock); in xfs_alloc_zone_info()
1189 init_waitqueue_head(&zi->zi_zone_wait); in xfs_alloc_zone_info()
1190 spin_lock_init(&zi->zi_used_buckets_lock); in xfs_alloc_zone_info()
1192 zi->zi_used_bucket_bitmap[i] = xfs_alloc_bucket_bitmap(mp); in xfs_alloc_zone_info()
1193 if (!zi->zi_used_bucket_bitmap[i]) in xfs_alloc_zone_info()
1199 while (--i > 0) in xfs_alloc_zone_info()
1200 kvfree(zi->zi_used_bucket_bitmap[i]); in xfs_alloc_zone_info()
1213 kvfree(zi->zi_used_bucket_bitmap[i]); in xfs_free_zone_info()
1224 struct xfs_buftarg *bt = mp->m_rtdev_targp; in xfs_mount_zones()
1225 xfs_extlen_t zone_blocks = mp->m_groups[XG_TYPE_RTG].blocks; in xfs_mount_zones()
1230 return -EINVAL; in xfs_mount_zones()
1235 return -EFSCORRUPTED; in xfs_mount_zones()
1237 if (mp->m_sb.sb_rextsize != 1) { in xfs_mount_zones()
1239 return -EFSCORRUPTED; in xfs_mount_zones()
1241 if (mp->m_sb.sb_rgcount < XFS_MIN_ZONES) { in xfs_mount_zones()
1244 return -EFSCORRUPTED; in xfs_mount_zones()
1251 mp->m_zone_info = xfs_alloc_zone_info(mp); in xfs_mount_zones()
1252 if (!mp->m_zone_info) in xfs_mount_zones()
1253 return -ENOMEM; in xfs_mount_zones()
1256 mp->m_sb.sb_rgcount, zone_blocks, mp->m_max_open_zones); in xfs_mount_zones()
1269 * value also get applied to non-zoned files on the data device if in xfs_mount_zones()
1276 * the higher min_writeback_pages for non-RT inodes is either a noop in xfs_mount_zones()
1279 mp->m_super->s_min_writeback_pages = in xfs_mount_zones()
1283 if (bdev_is_zoned(bt->bt_bdev)) { in xfs_mount_zones()
1284 error = blkdev_report_zones_cached(bt->bt_bdev, in xfs_mount_zones()
1285 XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart), in xfs_mount_zones()
1286 mp->m_sb.sb_rgcount, xfs_get_zone_info_cb, &iz); in xfs_mount_zones()
1310 mp->m_zonegc_low_space = 0; in xfs_mount_zones()
1318 xfs_free_zone_info(mp->m_zone_info); in xfs_mount_zones()
1327 xfs_free_zone_info(mp->m_zone_info); in xfs_unmount_zones()