linux/include/linux/devcoredump.h
<<
>>
Prefs
   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 */
  91