devcoredump.h (2266B)
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright(c) 2015 Intel Deutschland GmbH 4 */ 5#ifndef __DEVCOREDUMP_H 6#define __DEVCOREDUMP_H 7 8#include <linux/device.h> 9#include <linux/module.h> 10#include <linux/vmalloc.h> 11 12#include <linux/scatterlist.h> 13#include <linux/slab.h> 14 15/* 16 * _devcd_free_sgtable - free all the memory of the given scatterlist table 17 * (i.e. both pages and scatterlist instances) 18 * NOTE: if two tables allocated and chained using the sg_chain function then 19 * this function should be called only once on the first table 20 * @table: pointer to sg_table to free 21 */ 22static inline void _devcd_free_sgtable(struct scatterlist *table) 23{ 24 int i; 25 struct page *page; 26 struct scatterlist *iter; 27 struct scatterlist *delete_iter; 28 29 /* free pages */ 30 iter = table; 31 for_each_sg(table, iter, sg_nents(table), i) { 32 page = sg_page(iter); 33 if (page) 34 __free_page(page); 35 } 36 37 /* then free all chained tables */ 38 iter = table; 39 delete_iter = table; /* always points on a head of a table */ 40 while (!sg_is_last(iter)) { 41 iter++; 42 if (sg_is_chain(iter)) { 43 iter = sg_chain_ptr(iter); 44 kfree(delete_iter); 45 delete_iter = iter; 46 } 47 } 48 49 /* free the last table */ 50 kfree(delete_iter); 51} 52 53 54#ifdef CONFIG_DEV_COREDUMP 55void dev_coredumpv(struct device *dev, void *data, size_t datalen, 56 gfp_t gfp); 57 58void dev_coredumpm(struct device *dev, struct module *owner, 59 void *data, size_t datalen, gfp_t gfp, 60 ssize_t (*read)(char *buffer, loff_t offset, size_t count, 61 void *data, size_t datalen), 62 void (*free)(void *data)); 63 64void dev_coredumpsg(struct device *dev, struct scatterlist *table, 65 size_t datalen, gfp_t gfp); 66#else 67static inline void dev_coredumpv(struct device *dev, void *data, 68 size_t datalen, gfp_t gfp) 69{ 70 vfree(data); 71} 72 73static inline void 74dev_coredumpm(struct device *dev, struct module *owner, 75 void *data, size_t datalen, gfp_t gfp, 76 ssize_t (*read)(char *buffer, loff_t offset, size_t count, 77 void *data, size_t datalen), 78 void (*free)(void *data)) 79{ 80 free(data); 81} 82 83static inline void dev_coredumpsg(struct device *dev, struct scatterlist *table, 84 size_t datalen, gfp_t gfp) 85{ 86 _devcd_free_sgtable(table); 87} 88#endif /* CONFIG_DEV_COREDUMP */ 89 90#endif /* __DEVCOREDUMP_H */