// SPDX-License-Identifier: GPL-2.0-only#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 "stats"staticintdm_stat_need_rcu_barrier;/* * Using 64-bit values to avoid overflow (which is a * problem that block/genhd.c's IO accounting has). */structdm_stat_percpu{unsignedlonglongsectors[2];unsignedlonglongios[2];unsignedlonglongmerges[2];unsignedlonglongticks[2];unsignedlonglongio_ticks[2];unsignedlonglongio_ticks_total;unsignedlonglongtime_in_queue;unsignedlonglong*histogram;};structdm_stat_shared{atomic_tin_flight[2];unsignedlonglongstamp;structdm_stat_percputmp;};structdm_stat{structlist_headlist_entry;intid;unsignedintstat_flags;size_tn_entries;sector_tstart;sector_tend;sector_tstep;unsignedintn_histogram_entries;unsignedlonglong*histogram_boundaries;constchar*program_id;constchar*aux_data;structrcu_headrcu_head;size_tshared_alloc_size;size_tpercpu_alloc_size;size_thistogram_alloc_size;structdm_stat_percpu*stat_percpu[NR_CPUS];structdm_stat_sharedstat_shared[]__counted_by(n_entries);};#define STAT_PRECISE_TIMESTAMPS 1structdm_stats_last_position{sector_tlast_sector;unsignedintlast_rw;};#define DM_STAT_MAX_ENTRIES 8388608#define DM_STAT_MAX_HISTOGRAM_ENTRIES 134217728/* * A typo on the command line could possibly make the kernel run out of memory * and crash. To prevent the crash we account all used memory. We fail if we * exhaust 1/4 of all memory or 1/2 of vmalloc space. */#define DM_STATS_MEMORY_FACTOR 4#define DM_STATS_VMALLOC_FACTOR 2staticDEFINE_SPINLOCK(shared_memory_lock);staticunsignedlongshared_memory_amount;staticbool__check_shared_memory(size_talloc_size){size_ta;a=shared_memory_amount+alloc_size;if(a<shared_memory_amount)returnfalse;if(a>>PAGE_SHIFT>totalram_pages()/DM_STATS_MEMORY_FACTOR)returnfalse;#ifdef CONFIG_MMUif(a>(VMALLOC_END-VMALLOC_START)/DM_STATS_VMALLOC_FACTOR)returnfalse;#endifreturntrue;}staticbool