cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ufshpb.h (8846B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Universal Flash Storage Host Performance Booster
      4 *
      5 * Copyright (C) 2017-2021 Samsung Electronics Co., Ltd.
      6 *
      7 * Authors:
      8 *	Yongmyung Lee <ymhungry.lee@samsung.com>
      9 *	Jinyoung Choi <j-young.choi@samsung.com>
     10 */
     11
     12#ifndef _UFSHPB_H_
     13#define _UFSHPB_H_
     14
     15/* hpb response UPIU macro */
     16#define HPB_RSP_NONE				0x0
     17#define HPB_RSP_REQ_REGION_UPDATE		0x1
     18#define HPB_RSP_DEV_RESET			0x2
     19#define MAX_ACTIVE_NUM				2
     20#define MAX_INACTIVE_NUM			2
     21#define DEV_DATA_SEG_LEN			0x14
     22#define DEV_SENSE_SEG_LEN			0x12
     23#define DEV_DES_TYPE				0x80
     24#define DEV_ADDITIONAL_LEN			0x10
     25
     26/* hpb map & entries macro */
     27#define HPB_RGN_SIZE_UNIT			512
     28#define HPB_ENTRY_BLOCK_SIZE			4096
     29#define HPB_ENTRY_SIZE				0x8
     30#define PINNED_NOT_SET				U32_MAX
     31
     32/* hpb support chunk size */
     33#define HPB_LEGACY_CHUNK_HIGH			1
     34#define HPB_MULTI_CHUNK_HIGH			255
     35
     36/* hpb vender defined opcode */
     37#define UFSHPB_READ				0xF8
     38#define UFSHPB_READ_BUFFER			0xF9
     39#define UFSHPB_READ_BUFFER_ID			0x01
     40#define UFSHPB_WRITE_BUFFER			0xFA
     41#define UFSHPB_WRITE_BUFFER_INACT_SINGLE_ID	0x01
     42#define UFSHPB_WRITE_BUFFER_PREFETCH_ID		0x02
     43#define UFSHPB_WRITE_BUFFER_INACT_ALL_ID	0x03
     44#define HPB_WRITE_BUFFER_CMD_LENGTH		10
     45#define MAX_HPB_READ_ID				0x7F
     46#define HPB_READ_BUFFER_CMD_LENGTH		10
     47#define LU_ENABLED_HPB_FUNC			0x02
     48
     49#define HPB_RESET_REQ_RETRIES			10
     50#define HPB_MAP_REQ_RETRIES			5
     51#define HPB_REQUEUE_TIME_MS			0
     52
     53#define HPB_SUPPORT_VERSION			0x200
     54#define HPB_SUPPORT_LEGACY_VERSION		0x100
     55
     56enum UFSHPB_MODE {
     57	HPB_HOST_CONTROL,
     58	HPB_DEVICE_CONTROL,
     59};
     60
     61enum UFSHPB_STATE {
     62	HPB_INIT,
     63	HPB_PRESENT,
     64	HPB_SUSPEND,
     65	HPB_FAILED,
     66	HPB_RESET,
     67};
     68
     69enum HPB_RGN_STATE {
     70	HPB_RGN_INACTIVE,
     71	HPB_RGN_ACTIVE,
     72	/* pinned regions are always active */
     73	HPB_RGN_PINNED,
     74};
     75
     76enum HPB_SRGN_STATE {
     77	HPB_SRGN_UNUSED,
     78	HPB_SRGN_INVALID,
     79	HPB_SRGN_VALID,
     80	HPB_SRGN_ISSUED,
     81};
     82
     83/**
     84 * struct ufshpb_lu_info - UFSHPB logical unit related info
     85 * @num_blocks: the number of logical block
     86 * @pinned_start: the start region number of pinned region
     87 * @num_pinned: the number of pinned regions
     88 * @max_active_rgns: maximum number of active regions
     89 */
     90struct ufshpb_lu_info {
     91	int num_blocks;
     92	int pinned_start;
     93	int num_pinned;
     94	int max_active_rgns;
     95};
     96
     97struct ufshpb_map_ctx {
     98	struct page **m_page;
     99	unsigned long *ppn_dirty;
    100};
    101
    102struct ufshpb_subregion {
    103	struct ufshpb_map_ctx *mctx;
    104	enum HPB_SRGN_STATE srgn_state;
    105	int rgn_idx;
    106	int srgn_idx;
    107	bool is_last;
    108
    109	/* subregion reads - for host mode */
    110	unsigned int reads;
    111
    112	/* below information is used by rsp_list */
    113	struct list_head list_act_srgn;
    114};
    115
    116struct ufshpb_region {
    117	struct ufshpb_lu *hpb;
    118	struct ufshpb_subregion *srgn_tbl;
    119	enum HPB_RGN_STATE rgn_state;
    120	int rgn_idx;
    121	int srgn_cnt;
    122
    123	/* below information is used by rsp_list */
    124	struct list_head list_inact_rgn;
    125
    126	/* below information is used by lru */
    127	struct list_head list_lru_rgn;
    128	unsigned long rgn_flags;
    129#define RGN_FLAG_DIRTY 0
    130#define RGN_FLAG_UPDATE 1
    131
    132	/* region reads - for host mode */
    133	spinlock_t rgn_lock;
    134	unsigned int reads;
    135	/* region "cold" timer - for host mode */
    136	ktime_t read_timeout;
    137	unsigned int read_timeout_expiries;
    138	struct list_head list_expired_rgn;
    139};
    140
    141#define for_each_sub_region(rgn, i, srgn)				\
    142	for ((i) = 0;							\
    143	     ((i) < (rgn)->srgn_cnt) && ((srgn) = &(rgn)->srgn_tbl[i]); \
    144	     (i)++)
    145
    146/**
    147 * struct ufshpb_req - HPB related request structure (write/read buffer)
    148 * @req: block layer request structure
    149 * @bio: bio for this request
    150 * @hpb: ufshpb_lu structure that related to
    151 * @list_req: ufshpb_req mempool list
    152 * @sense: store its sense data
    153 * @mctx: L2P map information
    154 * @rgn_idx: target region index
    155 * @srgn_idx: target sub-region index
    156 * @lun: target logical unit number
    157 * @m_page: L2P map information data for pre-request
    158 * @len: length of host-side cached L2P map in m_page
    159 * @lpn: start LPN of L2P map in m_page
    160 */
    161struct ufshpb_req {
    162	struct request *req;
    163	struct bio *bio;
    164	struct ufshpb_lu *hpb;
    165	struct list_head list_req;
    166	union {
    167		struct {
    168			struct ufshpb_map_ctx *mctx;
    169			unsigned int rgn_idx;
    170			unsigned int srgn_idx;
    171			unsigned int lun;
    172		} rb;
    173		struct {
    174			struct page *m_page;
    175			unsigned int len;
    176			unsigned long lpn;
    177		} wb;
    178	};
    179};
    180
    181struct victim_select_info {
    182	struct list_head lh_lru_rgn; /* LRU list of regions */
    183	int max_lru_active_cnt; /* supported hpb #region - pinned #region */
    184	atomic_t active_cnt;
    185};
    186
    187/**
    188 * ufshpb_params - ufs hpb parameters
    189 * @requeue_timeout_ms - requeue threshold of wb command (0x2)
    190 * @activation_thld - min reads [IOs] to activate/update a region
    191 * @normalization_factor - shift right the region's reads
    192 * @eviction_thld_enter - min reads [IOs] for the entering region in eviction
    193 * @eviction_thld_exit - max reads [IOs] for the exiting region in eviction
    194 * @read_timeout_ms - timeout [ms] from the last read IO to the region
    195 * @read_timeout_expiries - amount of allowable timeout expireis
    196 * @timeout_polling_interval_ms - frequency in which timeouts are checked
    197 * @inflight_map_req - number of inflight map requests
    198 */
    199struct ufshpb_params {
    200	unsigned int requeue_timeout_ms;
    201	unsigned int activation_thld;
    202	unsigned int normalization_factor;
    203	unsigned int eviction_thld_enter;
    204	unsigned int eviction_thld_exit;
    205	unsigned int read_timeout_ms;
    206	unsigned int read_timeout_expiries;
    207	unsigned int timeout_polling_interval_ms;
    208	unsigned int inflight_map_req;
    209};
    210
    211struct ufshpb_stats {
    212	u64 hit_cnt;
    213	u64 miss_cnt;
    214	u64 rcmd_noti_cnt;
    215	u64 rcmd_active_cnt;
    216	u64 rcmd_inactive_cnt;
    217	u64 map_req_cnt;
    218	u64 pre_req_cnt;
    219	u64 umap_req_cnt;
    220};
    221
    222struct ufshpb_lu {
    223	int lun;
    224	struct scsi_device *sdev_ufs_lu;
    225
    226	spinlock_t rgn_state_lock; /* for protect rgn/srgn state */
    227	struct ufshpb_region *rgn_tbl;
    228
    229	atomic_t hpb_state;
    230
    231	spinlock_t rsp_list_lock;
    232	struct list_head lh_act_srgn; /* hold rsp_list_lock */
    233	struct list_head lh_inact_rgn; /* hold rsp_list_lock */
    234
    235	/* pre request information */
    236	struct ufshpb_req *pre_req;
    237	int num_inflight_pre_req;
    238	int throttle_pre_req;
    239	int num_inflight_map_req; /* hold param_lock */
    240	spinlock_t param_lock;
    241
    242	struct list_head lh_pre_req_free;
    243	int pre_req_max_tr_len;
    244
    245	/* cached L2P map management worker */
    246	struct work_struct map_work;
    247
    248	/* for selecting victim */
    249	struct victim_select_info lru_info;
    250	struct work_struct ufshpb_normalization_work;
    251	struct delayed_work ufshpb_read_to_work;
    252	unsigned long work_data_bits;
    253#define TIMEOUT_WORK_RUNNING 0
    254
    255	/* pinned region information */
    256	u32 lu_pinned_start;
    257	u32 lu_pinned_end;
    258
    259	/* HPB related configuration */
    260	u32 rgns_per_lu;
    261	u32 srgns_per_lu;
    262	u32 last_srgn_entries;
    263	int srgns_per_rgn;
    264	u32 srgn_mem_size;
    265	u32 entries_per_rgn_mask;
    266	u32 entries_per_rgn_shift;
    267	u32 entries_per_srgn;
    268	u32 entries_per_srgn_mask;
    269	u32 entries_per_srgn_shift;
    270	u32 pages_per_srgn;
    271
    272	bool is_hcm;
    273
    274	struct ufshpb_stats stats;
    275	struct ufshpb_params params;
    276
    277	struct kmem_cache *map_req_cache;
    278	struct kmem_cache *m_page_cache;
    279
    280	struct list_head list_hpb_lu;
    281};
    282
    283struct ufs_hba;
    284struct ufshcd_lrb;
    285
    286#ifndef CONFIG_SCSI_UFS_HPB
    287static int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { return 0; }
    288static void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {}
    289static void ufshpb_resume(struct ufs_hba *hba) {}
    290static void ufshpb_suspend(struct ufs_hba *hba) {}
    291static void ufshpb_toggle_state(struct ufs_hba *hba, enum UFSHPB_STATE src, enum UFSHPB_STATE dest) {}
    292static void ufshpb_init(struct ufs_hba *hba) {}
    293static void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) {}
    294static void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) {}
    295static void ufshpb_remove(struct ufs_hba *hba) {}
    296static bool ufshpb_is_allowed(struct ufs_hba *hba) { return false; }
    297static void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) {}
    298static void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) {}
    299static bool ufshpb_is_legacy(struct ufs_hba *hba) { return false; }
    300#else
    301int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp);
    302void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp);
    303void ufshpb_resume(struct ufs_hba *hba);
    304void ufshpb_suspend(struct ufs_hba *hba);
    305void ufshpb_toggle_state(struct ufs_hba *hba, enum UFSHPB_STATE src, enum UFSHPB_STATE dest);
    306void ufshpb_init(struct ufs_hba *hba);
    307void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev);
    308void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev);
    309void ufshpb_remove(struct ufs_hba *hba);
    310bool ufshpb_is_allowed(struct ufs_hba *hba);
    311void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf);
    312void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf);
    313bool ufshpb_is_legacy(struct ufs_hba *hba);
    314extern struct attribute_group ufs_sysfs_hpb_stat_group;
    315extern struct attribute_group ufs_sysfs_hpb_param_group;
    316#endif
    317
    318#endif /* End of Header */