/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Rolling buffer of folios * * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) */ #ifndef _ROLLING_BUFFER_H #define _ROLLING_BUFFER_H #include #include /* * Rolling buffer. Whilst the buffer is live and in use, folios and bvecq * segments can be added to one end by one thread and removed from the other * end by another thread. The buffer isn't allowed to be empty; it must always * have at least one bvecq in it so that neither side has to modify both queue * pointers. * * The iterator in the buffer is extended as buffers are inserted. It can be * snapshotted to use a segment of the buffer. */ struct rolling_buffer { struct bvecq *head; /* Producer's insertion point */ struct bvecq *tail; /* Consumer's removal point */ struct iov_iter iter; /* Iterator tracking what's left in the buffer */ u8 first_tail_slot; /* First slot in ->tail */ bool for_writeback; /* T if being used for writeback */ }; int rolling_buffer_init(struct rolling_buffer *roll, unsigned int direction, gfp_t gfp, bool for_writeback); int rolling_buffer_make_space(struct rolling_buffer *roll, gfp_t gfp); ssize_t rolling_buffer_bulk_load_from_ra(struct rolling_buffer *roll, struct readahead_control *ractl, gfp_t gfp); ssize_t rolling_buffer_append(struct rolling_buffer *roll, struct folio *folio, gfp_t gfp); struct bvecq *rolling_buffer_delete_spent(struct rolling_buffer *roll); void rolling_buffer_clear(struct rolling_buffer *roll); static inline void rolling_buffer_advance(struct rolling_buffer *roll, size_t amount) { iov_iter_advance(&roll->iter, amount); } #endif /* _ROLLING_BUFFER_H */