13d0407baSopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
23d0407baSopenharmony_ci
33d0407baSopenharmony_ci#ifndef DEFERRED_FREE_HELPER_H
43d0407baSopenharmony_ci#define DEFERRED_FREE_HELPER_H
53d0407baSopenharmony_ci
63d0407baSopenharmony_ci/**
73d0407baSopenharmony_ci * df_reason - enum for reason why item was freed
83d0407baSopenharmony_ci *
93d0407baSopenharmony_ci * This provides a reason for why the free function was called
103d0407baSopenharmony_ci * on the item. This is useful when deferred_free is used in
113d0407baSopenharmony_ci * combination with a pagepool, so under pressure the page can
123d0407baSopenharmony_ci * be immediately freed.
133d0407baSopenharmony_ci *
143d0407baSopenharmony_ci * DF_NORMAL:         Normal deferred free
153d0407baSopenharmony_ci *
163d0407baSopenharmony_ci * DF_UNDER_PRESSURE: Free was called because the system
173d0407baSopenharmony_ci *                    is under memory pressure. Usually
183d0407baSopenharmony_ci *                    from a shrinker. Avoid allocating
193d0407baSopenharmony_ci *                    memory in the free call, as it may
203d0407baSopenharmony_ci *                    fail.
213d0407baSopenharmony_ci */
223d0407baSopenharmony_cienum df_reason {
233d0407baSopenharmony_ci	DF_NORMAL,
243d0407baSopenharmony_ci	DF_UNDER_PRESSURE,
253d0407baSopenharmony_ci};
263d0407baSopenharmony_ci
273d0407baSopenharmony_ci/**
283d0407baSopenharmony_ci * deferred_freelist_item - item structure for deferred freelist
293d0407baSopenharmony_ci *
303d0407baSopenharmony_ci * This is to be added to the structure for whatever you want to
313d0407baSopenharmony_ci * defer freeing on.
323d0407baSopenharmony_ci *
333d0407baSopenharmony_ci * @nr_pages: number of pages used by item to be freed
343d0407baSopenharmony_ci * @free: function pointer to be called when freeing the item
353d0407baSopenharmony_ci * @list: list entry for the deferred list
363d0407baSopenharmony_ci */
373d0407baSopenharmony_cistruct deferred_freelist_item {
383d0407baSopenharmony_ci	size_t nr_pages;
393d0407baSopenharmony_ci	void (*free)(struct deferred_freelist_item *i,
403d0407baSopenharmony_ci		     enum df_reason reason);
413d0407baSopenharmony_ci	struct list_head list;
423d0407baSopenharmony_ci};
433d0407baSopenharmony_ci
443d0407baSopenharmony_ci/**
453d0407baSopenharmony_ci * deferred_free - call to add item to the deferred free list
463d0407baSopenharmony_ci *
473d0407baSopenharmony_ci * @item: Pointer to deferred_freelist_item field of a structure
483d0407baSopenharmony_ci * @free: Function pointer to the free call
493d0407baSopenharmony_ci * @nr_pages: number of pages to be freed
503d0407baSopenharmony_ci */
513d0407baSopenharmony_civoid deferred_free(struct deferred_freelist_item *item,
523d0407baSopenharmony_ci		   void (*free)(struct deferred_freelist_item *i,
533d0407baSopenharmony_ci				enum df_reason reason),
543d0407baSopenharmony_ci		   size_t nr_pages);
553d0407baSopenharmony_ci
563d0407baSopenharmony_ciunsigned long get_freelist_nr_pages(void);
573d0407baSopenharmony_ci#endif
58