107 lines
3.2 KiB
C
107 lines
3.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (c) 2026, Google LLC.
|
|
* Pasha Tatashin <pasha.tatashin@soleen.com>
|
|
*/
|
|
|
|
#ifndef _LINUX_KHO_BLOCK_H
|
|
#define _LINUX_KHO_BLOCK_H
|
|
|
|
#include <linux/list.h>
|
|
#include <linux/types.h>
|
|
#include <linux/kho/abi/block.h>
|
|
|
|
/**
|
|
* struct kho_block - Internal representation of a serialization block.
|
|
* @list: List head for linking blocks in memory.
|
|
* @ser: Pointer to the serialized header in preserved memory.
|
|
*/
|
|
struct kho_block {
|
|
struct list_head list;
|
|
struct kho_block_header_ser *ser;
|
|
};
|
|
|
|
/**
|
|
* struct kho_block_set - A set of blocks containing serialized entries of the same type.
|
|
* @blocks: The list of serialization blocks (struct kho_block).
|
|
* @nblocks: The number of allocated serialization blocks.
|
|
* @head_pa: Physical address of the first block header.
|
|
* @entry_size: The size of each entry in the blocks.
|
|
* @count_per_block: The maximum number of entries each block can hold.
|
|
* @incoming: True if this block set was restored from the previous kernel.
|
|
*
|
|
* Note: Synchronization and locking are the responsibility of the caller.
|
|
* The block set structure itself is not internally synchronized.
|
|
*/
|
|
struct kho_block_set {
|
|
struct list_head blocks;
|
|
long nblocks;
|
|
u64 head_pa;
|
|
size_t entry_size;
|
|
u64 count_per_block;
|
|
bool incoming;
|
|
};
|
|
|
|
/**
|
|
* struct kho_block_set_it - Iterator for serializing entries into blocks.
|
|
* @bs: The block set being iterated.
|
|
* @block: The current block.
|
|
* @i: The current entry index within @block.
|
|
*/
|
|
struct kho_block_set_it {
|
|
struct kho_block_set *bs;
|
|
struct kho_block *block;
|
|
u64 i;
|
|
};
|
|
|
|
/**
|
|
* KHO_BLOCK_SET_INIT - Initialize a static kho_block_set.
|
|
* @_name: Name of the kho_block_set variable.
|
|
* @_entry_size: The size of each entry in the block set.
|
|
*/
|
|
#define KHO_BLOCK_SET_INIT(_name, _entry_size) { \
|
|
.blocks = LIST_HEAD_INIT((_name).blocks), \
|
|
.entry_size = _entry_size, \
|
|
.count_per_block = (KHO_BLOCK_SIZE - \
|
|
sizeof(struct kho_block_header_ser)) / \
|
|
(_entry_size), \
|
|
}
|
|
|
|
void kho_block_set_init(struct kho_block_set *bs, size_t entry_size);
|
|
|
|
int kho_block_set_grow(struct kho_block_set *bs, u64 count);
|
|
void kho_block_set_shrink(struct kho_block_set *bs, u64 count);
|
|
|
|
int kho_block_set_restore(struct kho_block_set *bs, u64 head_pa);
|
|
void kho_block_set_destroy(struct kho_block_set *bs);
|
|
void kho_block_set_clear(struct kho_block_set *bs);
|
|
|
|
/**
|
|
* kho_block_set_head_pa - Get the physical address of the first block header.
|
|
* @bs: The block set.
|
|
*
|
|
* Return: The physical address of the first block header, or 0 if empty.
|
|
*/
|
|
static inline u64 kho_block_set_head_pa(struct kho_block_set *bs)
|
|
{
|
|
return bs->head_pa;
|
|
}
|
|
|
|
/**
|
|
* kho_block_set_is_empty - Check if the block set has no allocated blocks.
|
|
* @bs: The block set.
|
|
*
|
|
* Return: True if there are no blocks in the set, false otherwise.
|
|
*/
|
|
static inline bool kho_block_set_is_empty(struct kho_block_set *bs)
|
|
{
|
|
return list_empty(&bs->blocks);
|
|
}
|
|
|
|
void kho_block_set_it_init(struct kho_block_set_it *it, struct kho_block_set *bs);
|
|
void *kho_block_set_it_reserve_entry(struct kho_block_set_it *it);
|
|
void *kho_block_set_it_read_entry(struct kho_block_set_it *it);
|
|
void *kho_block_set_it_prev(struct kho_block_set_it *it);
|
|
|
|
#endif /* _LINUX_KHO_BLOCK_H */
|