#include <linux/errno.h>
#include <linux/numa.h>
#include <linux/slab.h>
#include <linux/rculist.h>
#include <linux/threads.h>
#include <linux/preempt.h>
#include <linux/irqflags.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/device-mapper.h>
#include "dm-core.h"
#include "dm-stats.h"
#define DM_MSG_PREFIX …
static int dm_stat_need_rcu_barrier;
struct dm_stat_percpu { … };
struct dm_stat_shared { … };
struct dm_stat { … };
#define STAT_PRECISE_TIMESTAMPS …
struct dm_stats_last_position { … };
#define DM_STAT_MAX_ENTRIES …
#define DM_STAT_MAX_HISTOGRAM_ENTRIES …
#define DM_STATS_MEMORY_FACTOR …
#define DM_STATS_VMALLOC_FACTOR …
static DEFINE_SPINLOCK(shared_memory_lock);
static unsigned long shared_memory_amount;
static bool __check_shared_memory(size_t alloc_size)
{ … }
static bool check_shared_memory(size_t alloc_size)
{ … }
static bool claim_shared_memory(size_t alloc_size)
{ … }
static void free_shared_memory(size_t alloc_size)
{ … }
static void *dm_kvzalloc(size_t alloc_size, int node)
{ … }
static void dm_kvfree(void *ptr, size_t alloc_size)
{ … }
static void dm_stat_free(struct rcu_head *head)
{ … }
static int dm_stat_in_flight(struct dm_stat_shared *shared)
{ … }
int dm_stats_init(struct dm_stats *stats)
{ … }
void dm_stats_cleanup(struct dm_stats *stats)
{ … }
static void dm_stats_recalc_precise_timestamps(struct dm_stats *stats)
{ … }
static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end,
sector_t step, unsigned int stat_flags,
unsigned int n_histogram_entries,
unsigned long long *histogram_boundaries,
const char *program_id, const char *aux_data,
void (*suspend_callback)(struct mapped_device *),
void (*resume_callback)(struct mapped_device *),
struct mapped_device *md)
{ … }
static struct dm_stat *__dm_stats_find(struct dm_stats *stats, int id)
{ … }
static int dm_stats_delete(struct dm_stats *stats, int id)
{ … }
static int dm_stats_list(struct dm_stats *stats, const char *program,
char *result, unsigned int maxlen)
{ … }
static void dm_stat_round(struct dm_stat *s, struct dm_stat_shared *shared,
struct dm_stat_percpu *p)
{ … }
static void dm_stat_for_entry(struct dm_stat *s, size_t entry,
int idx, sector_t len,
struct dm_stats_aux *stats_aux, bool end,
unsigned long duration_jiffies)
{ … }
static void __dm_stat_bio(struct dm_stat *s, int bi_rw,
sector_t bi_sector, sector_t end_sector,
bool end, unsigned long duration_jiffies,
struct dm_stats_aux *stats_aux)
{ … }
void dm_stats_account_io(struct dm_stats *stats, unsigned long bi_rw,
sector_t bi_sector, unsigned int bi_sectors, bool end,
unsigned long start_time,
struct dm_stats_aux *stats_aux)
{ … }
static void __dm_stat_init_temporary_percpu_totals(struct dm_stat_shared *shared,
struct dm_stat *s, size_t x)
{ … }
static void __dm_stat_clear(struct dm_stat *s, size_t idx_start, size_t idx_end,
bool init_tmp_percpu_totals)
{ … }
static int dm_stats_clear(struct dm_stats *stats, int id)
{ … }
static unsigned long long dm_jiffies_to_msec64(struct dm_stat *s, unsigned long long j)
{ … }
static int dm_stats_print(struct dm_stats *stats, int id,
size_t idx_start, size_t idx_len,
bool clear, char *result, unsigned int maxlen)
{ … }
static int dm_stats_set_aux(struct dm_stats *stats, int id, const char *aux_data)
{ … }
static int parse_histogram(const char *h, unsigned int *n_histogram_entries,
unsigned long long **histogram_boundaries)
{ … }
static int message_stats_create(struct mapped_device *md,
unsigned int argc, char **argv,
char *result, unsigned int maxlen)
{ … }
static int message_stats_delete(struct mapped_device *md,
unsigned int argc, char **argv)
{ … }
static int message_stats_clear(struct mapped_device *md,
unsigned int argc, char **argv)
{ … }
static int message_stats_list(struct mapped_device *md,
unsigned int argc, char **argv,
char *result, unsigned int maxlen)
{ … }
static int message_stats_print(struct mapped_device *md,
unsigned int argc, char **argv, bool clear,
char *result, unsigned int maxlen)
{ … }
static int message_stats_set_aux(struct mapped_device *md,
unsigned int argc, char **argv)
{ … }
int dm_stats_message(struct mapped_device *md, unsigned int argc, char **argv,
char *result, unsigned int maxlen)
{ … }
int __init dm_statistics_init(void)
{ … }
void dm_statistics_exit(void)
{ … }
module_param_named(stats_current_allocated_bytes, shared_memory_amount, ulong, 0444);
MODULE_PARM_DESC(…) …;