at v6.15-rc6 2.2 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-or-later */ 2/* Rolling buffer of folios 3 * 4 * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8#ifndef _ROLLING_BUFFER_H 9#define _ROLLING_BUFFER_H 10 11#include <linux/folio_queue.h> 12#include <linux/uio.h> 13 14/* 15 * Rolling buffer. Whilst the buffer is live and in use, folios and folio 16 * queue segments can be added to one end by one thread and removed from the 17 * other end by another thread. The buffer isn't allowed to be empty; it must 18 * always have at least one folio_queue in it so that neither side has to 19 * modify both queue pointers. 20 * 21 * The iterator in the buffer is extended as buffers are inserted. It can be 22 * snapshotted to use a segment of the buffer. 23 */ 24struct rolling_buffer { 25 struct folio_queue *head; /* Producer's insertion point */ 26 struct folio_queue *tail; /* Consumer's removal point */ 27 struct iov_iter iter; /* Iterator tracking what's left in the buffer */ 28 u8 next_head_slot; /* Next slot in ->head */ 29 u8 first_tail_slot; /* First slot in ->tail */ 30}; 31 32/* 33 * Snapshot of a rolling buffer. 34 */ 35struct rolling_buffer_snapshot { 36 struct folio_queue *curr_folioq; /* Queue segment in which current folio resides */ 37 unsigned char curr_slot; /* Folio currently being read */ 38 unsigned char curr_order; /* Order of folio */ 39}; 40 41/* Marks to store per-folio in the internal folio_queue structs. */ 42#define ROLLBUF_MARK_1 BIT(0) 43#define ROLLBUF_MARK_2 BIT(1) 44 45int rolling_buffer_init(struct rolling_buffer *roll, unsigned int rreq_id, 46 unsigned int direction); 47int rolling_buffer_make_space(struct rolling_buffer *roll); 48ssize_t rolling_buffer_load_from_ra(struct rolling_buffer *roll, 49 struct readahead_control *ractl, 50 struct folio_batch *put_batch); 51ssize_t rolling_buffer_append(struct rolling_buffer *roll, struct folio *folio, 52 unsigned int flags); 53struct folio_queue *rolling_buffer_delete_spent(struct rolling_buffer *roll); 54void rolling_buffer_clear(struct rolling_buffer *roll); 55 56static inline void rolling_buffer_advance(struct rolling_buffer *roll, size_t amount) 57{ 58 iov_iter_advance(&roll->iter, amount); 59} 60 61#endif /* _ROLLING_BUFFER_H */