Linux Audio

Check our new training course

Loading...
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright 2023 Red Hat
  4 */
  5
  6#ifndef VDO_PHYSICAL_ZONE_H
  7#define VDO_PHYSICAL_ZONE_H
  8
  9#include <linux/atomic.h>
 10
 11#include "types.h"
 12
 13/*
 14 * The type of a PBN lock.
 15 */
 16enum pbn_lock_type {
 17	VIO_READ_LOCK,
 18	VIO_WRITE_LOCK,
 19	VIO_BLOCK_MAP_WRITE_LOCK,
 20};
 21
 22struct pbn_lock_implementation;
 23
 24/*
 25 * A PBN lock.
 26 */
 27struct pbn_lock {
 28	/* The implementation of the lock */
 29	const struct pbn_lock_implementation *implementation;
 30
 31	/* The number of VIOs holding or sharing this lock */
 32	data_vio_count_t holder_count;
 33	/*
 34	 * The number of compressed block writers holding a share of this lock while they are
 35	 * acquiring a reference to the PBN.
 36	 */
 37	u8 fragment_locks;
 38
 39	/* Whether the locked PBN has been provisionally referenced on behalf of the lock holder. */
 40	bool has_provisional_reference;
 41
 42	/*
 43	 * For read locks, the number of references that were known to be available on the locked
 44	 * block at the time the lock was acquired.
 45	 */
 46	u8 increment_limit;
 47
 48	/*
 49	 * For read locks, the number of data_vios that have tried to claim one of the available
 50	 * increments during the lifetime of the lock. Each claim will first increment this
 51	 * counter, so it can exceed the increment limit.
 52	 */
 53	atomic_t increments_claimed;
 54};
 55
 56struct physical_zone {
 57	/* Which physical zone this is */
 58	zone_count_t zone_number;
 59	/* The thread ID for this zone */
 60	thread_id_t thread_id;
 61	/* In progress operations keyed by PBN */
 62	struct int_map *pbn_operations;
 63	/* Pool of unused pbn_lock instances */
 64	struct pbn_lock_pool *lock_pool;
 65	/* The block allocator for this zone */
 66	struct block_allocator *allocator;
 67	/* The next zone from which to attempt an allocation */
 68	struct physical_zone *next;
 69};
 70
 71struct physical_zones {
 72	/* The number of zones */
 73	zone_count_t zone_count;
 74	/* The physical zones themselves */
 75	struct physical_zone zones[];
 76};
 77
 78bool __must_check vdo_is_pbn_read_lock(const struct pbn_lock *lock);
 79void vdo_downgrade_pbn_write_lock(struct pbn_lock *lock, bool compressed_write);
 80bool __must_check vdo_claim_pbn_lock_increment(struct pbn_lock *lock);
 81
 82/**
 83 * vdo_pbn_lock_has_provisional_reference() - Check whether a PBN lock has a provisional reference.
 84 * @lock: The PBN lock.
 85 */
 86static inline bool vdo_pbn_lock_has_provisional_reference(struct pbn_lock *lock)
 87{
 88	return ((lock != NULL) && lock->has_provisional_reference);
 89}
 90
 91void vdo_assign_pbn_lock_provisional_reference(struct pbn_lock *lock);
 92void vdo_unassign_pbn_lock_provisional_reference(struct pbn_lock *lock);
 93
 94int __must_check vdo_make_physical_zones(struct vdo *vdo,
 95					 struct physical_zones **zones_ptr);
 96
 97void vdo_free_physical_zones(struct physical_zones *zones);
 98
 99struct pbn_lock * __must_check vdo_get_physical_zone_pbn_lock(struct physical_zone *zone,
100							      physical_block_number_t pbn);
101
102int __must_check vdo_attempt_physical_zone_pbn_lock(struct physical_zone *zone,
103						    physical_block_number_t pbn,
104						    enum pbn_lock_type type,
105						    struct pbn_lock **lock_ptr);
106
107bool __must_check vdo_allocate_block_in_zone(struct data_vio *data_vio);
108
109void vdo_release_physical_zone_pbn_lock(struct physical_zone *zone,
110					physical_block_number_t locked_pbn,
111					struct pbn_lock *lock);
112
113void vdo_dump_physical_zone(const struct physical_zone *zone);
114
115#endif /* VDO_PHYSICAL_ZONE_H */