File Index
Files and directories
Sign in
FILE

packer.h

File preview with syntax highlighting.

linux-6.19.14/drivers/md/dm-vdo/packer.h C
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright 2023 Red Hat
  4 */
  5
  6#ifndef VDO_PACKER_H
  7#define VDO_PACKER_H
  8
  9#include <linux/list.h>
 10
 11#include "admin-state.h"
 12#include "constants.h"
 13#include "encodings.h"
 14#include "statistics.h"
 15#include "types.h"
 16#include "wait-queue.h"
 17
 18enum {
 19	DEFAULT_PACKER_BINS = 16,
 20};
 21
 22/* The header of a compressed block. */
 23struct compressed_block_header {
 24	/* Unsigned 32-bit major and minor versions, little-endian */
 25	struct packed_version_number version;
 26
 27	/* List of unsigned 16-bit compressed block sizes, little-endian */
 28	__le16 sizes[VDO_MAX_COMPRESSION_SLOTS];
 29} __packed;
 30
 31enum {
 32	VDO_COMPRESSED_BLOCK_DATA_SIZE = VDO_BLOCK_SIZE - sizeof(struct compressed_block_header),
 33
 34	/*
 35	 * A compressed block is only written if we can pack at least two fragments into it, so a
 36	 * fragment which fills the entire data portion of a compressed block is too big.
 37	 */
 38	VDO_MAX_COMPRESSED_FRAGMENT_SIZE = VDO_COMPRESSED_BLOCK_DATA_SIZE - 1,
 39};
 40
 41/* * The compressed block overlay. */
 42struct compressed_block {
 43	struct compressed_block_header header;
 44	char data[VDO_COMPRESSED_BLOCK_DATA_SIZE];
 45} __packed;
 46
 47/*
 48 * Each packer_bin holds an incomplete batch of data_vios that only partially fill a compressed
 49 * block. The bins are kept in a list sorted by the amount of unused space so the first bin with
 50 * enough space to hold a newly-compressed data_vio can easily be found. When the bin fills up or
 51 * is flushed, the first uncanceled data_vio in the bin is selected to be the agent for that bin.
 52 * Upon entering the packer, each data_vio already has its compressed data in the first slot of the
 53 * data_vio's compressed_block (overlaid on the data_vio's scratch_block). So the agent's fragment
 54 * is already in place. The fragments for the other uncanceled data_vios in the bin are packed into
 55 * the agent's compressed block. The agent then writes out the compressed block. If the write is
 56 * successful, the agent shares its pbn lock which each of the other data_vios in its compressed
 57 * block and sends each on its way. Finally the agent itself continues on the write path as before.
 58 *
 59 * There is one special bin which is used to hold data_vios which have been canceled and removed
 60 * from their bin by the packer. These data_vios need to wait for the canceller to rendezvous with
 61 * them and so they sit in this special bin.
 62 */
 63struct packer_bin {
 64	/* List links for packer.packer_bins */
 65	struct list_head list;
 66	/* The number of items in the bin */
 67	slot_number_t slots_used;
 68	/* The number of compressed block bytes remaining in the current batch */
 69	size_t free_space;
 70	/* The current partial batch of data_vios, waiting for more */
 71	struct data_vio *incoming[];
 72};
 73
 74struct packer {
 75	/* The ID of the packer's callback thread */
 76	thread_id_t thread_id;
 77	/* The number of bins */
 78	block_count_t size;
 79	/* A list of all packer_bins, kept sorted by free_space */
 80	struct list_head bins;
 81	/*
 82	 * A bin to hold data_vios which were canceled out of the packer and are waiting to
 83	 * rendezvous with the canceling data_vio.
 84	 */
 85	struct packer_bin *canceled_bin;
 86
 87	/* The current flush generation */
 88	sequence_number_t flush_generation;
 89
 90	/* The administrative state of the packer */
 91	struct admin_state state;
 92
 93	/* Statistics are only updated on the packer thread, but are accessed from other threads */
 94	struct packer_statistics statistics;
 95};
 96
 97int vdo_get_compressed_block_fragment(enum block_mapping_state mapping_state,
 98				      struct compressed_block *block,
 99				      u16 *fragment_offset, u16 *fragment_size);
100
101int __must_check vdo_make_packer(struct vdo *vdo, block_count_t bin_count,
102				 struct packer **packer_ptr);
103
104void vdo_free_packer(struct packer *packer);
105
106struct packer_statistics __must_check vdo_get_packer_statistics(const struct packer *packer);
107
108void vdo_attempt_packing(struct data_vio *data_vio);
109
110void vdo_flush_packer(struct packer *packer);
111
112void vdo_remove_lock_holder_from_packer(struct vdo_completion *completion);
113
114void vdo_increment_packer_flush_generation(struct packer *packer);
115
116void vdo_drain_packer(struct packer *packer, struct vdo_completion *completion);
117
118void vdo_resume_packer(struct packer *packer, struct vdo_completion *parent);
119
120void vdo_dump_packer(const struct packer *packer);
121
122#endif /* VDO_PACKER_H */
~/ Read-only file preview.