mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-17 10:41:26 +00:00
- Necessary cleanups in SGV cache for upcoming improvements. Particularly, all reclaiming management made per-pool, not global as before
- Shared between devices caches implemented git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@843 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1613,7 +1613,7 @@ struct scst_tgt_dev {
|
||||
|
||||
/*
|
||||
* Stored Unit Attention sense and its length for possible
|
||||
* subsequent RQUEST SENSE. Both protected by tgt_dev_lock.
|
||||
* subsequent REQUEST SENSE. Both protected by tgt_dev_lock.
|
||||
*/
|
||||
unsigned short tgt_dev_valid_sense_len;
|
||||
uint8_t tgt_dev_sense[SCST_SENSE_BUFFERSIZE];
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* include/scst_sgv.h
|
||||
*
|
||||
* Copyright (C) 2004 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
|
||||
* Copyright (C) 2004 - 2005 Leonid Stoljar
|
||||
* Copyright (C) 2007 - 2009 ID7 Ltd.
|
||||
*
|
||||
* Include file for SCST SGV cache.
|
||||
@@ -53,8 +52,8 @@ enum sgv_clustering_types {
|
||||
};
|
||||
|
||||
struct sgv_pool *sgv_pool_create(const char *name,
|
||||
enum sgv_clustering_types clustered);
|
||||
void sgv_pool_destroy(struct sgv_pool *pool);
|
||||
enum sgv_clustering_types clustered, bool shared);
|
||||
void sgv_pool_del(struct sgv_pool *pool);
|
||||
void sgv_pool_flush(struct sgv_pool *pool);
|
||||
|
||||
void sgv_pool_set_allocator(struct sgv_pool *pool,
|
||||
@@ -69,4 +68,5 @@ void sgv_pool_free(struct sgv_pool_obj *sgv, struct scst_mem_lim *mem_lim);
|
||||
void *sgv_get_priv(struct sgv_pool_obj *sgv);
|
||||
|
||||
void scst_init_mem_lim(struct scst_mem_lim *mem_lim);
|
||||
#endif /* ifndef __SCST_SGV_H */
|
||||
|
||||
#endif /* __SCST_SGV_H */
|
||||
|
||||
@@ -90,9 +90,11 @@ struct scst_user_opt {
|
||||
struct scst_user_dev_desc {
|
||||
aligned_u64 version_str;
|
||||
uint8_t type;
|
||||
uint8_t sgv_shared;
|
||||
struct scst_user_opt opt;
|
||||
uint32_t block_size;
|
||||
char name[SCST_MAX_NAME];
|
||||
char sgv_name[SCST_MAX_NAME];
|
||||
};
|
||||
|
||||
struct scst_user_sess {
|
||||
|
||||
@@ -1944,6 +1944,7 @@ static long dev_user_ioctl(struct file *file, unsigned int cmd,
|
||||
}
|
||||
TRACE_BUFFER("dev_desc", dev_desc, sizeof(*dev_desc));
|
||||
dev_desc->name[sizeof(dev_desc->name)-1] = '\0';
|
||||
dev_desc->sgv_name[sizeof(dev_desc->sgv_name)-1] = '\0';
|
||||
res = dev_user_register_dev(file, dev_desc);
|
||||
kfree(dev_desc);
|
||||
break;
|
||||
@@ -2708,22 +2709,27 @@ static int dev_user_register_dev(struct file *file,
|
||||
|
||||
scst_init_mem_lim(&dev->udev_mem_lim);
|
||||
|
||||
dev->pool = sgv_pool_create(dev->name, sgv_no_clustering);
|
||||
scnprintf(dev->devtype.name, sizeof(dev->devtype.name), "%s",
|
||||
(dev_desc->sgv_name[0] == '\0') ? dev->name :
|
||||
dev_desc->sgv_name);
|
||||
dev->pool = sgv_pool_create(dev->devtype.name, sgv_no_clustering,
|
||||
dev_desc->sgv_shared);
|
||||
if (dev->pool == NULL)
|
||||
goto out_free_dev;
|
||||
sgv_pool_set_allocator(dev->pool, dev_user_alloc_pages,
|
||||
dev_user_free_sg_entries);
|
||||
|
||||
scnprintf(dev->devtype.name, sizeof(dev->devtype.name), "%s-clust",
|
||||
dev->name);
|
||||
(dev_desc->sgv_name[0] == '\0') ? dev->name :
|
||||
dev_desc->sgv_name);
|
||||
dev->pool_clust = sgv_pool_create(dev->devtype.name,
|
||||
sgv_tail_clustering);
|
||||
sgv_tail_clustering, dev_desc->sgv_shared);
|
||||
if (dev->pool_clust == NULL)
|
||||
goto out_free0;
|
||||
sgv_pool_set_allocator(dev->pool_clust, dev_user_alloc_pages,
|
||||
dev_user_free_sg_entries);
|
||||
|
||||
scnprintf(dev->devtype.name, sizeof(dev->devtype.name), "dh-%s",
|
||||
scnprintf(dev->devtype.name, sizeof(dev->devtype.name), "%s",
|
||||
dev->name);
|
||||
dev->devtype.type = dev_desc->type;
|
||||
dev->devtype.threads_num = -1;
|
||||
@@ -2802,10 +2808,10 @@ out_del_free:
|
||||
spin_unlock(&dev_list_lock);
|
||||
|
||||
out_free:
|
||||
sgv_pool_destroy(dev->pool_clust);
|
||||
sgv_pool_del(dev->pool_clust);
|
||||
|
||||
out_free0:
|
||||
sgv_pool_destroy(dev->pool);
|
||||
sgv_pool_del(dev->pool);
|
||||
|
||||
out_free_dev:
|
||||
kfree(dev);
|
||||
@@ -3104,8 +3110,8 @@ static int dev_user_release(struct inode *inode, struct file *file)
|
||||
scst_unregister_virtual_device(dev->virt_id);
|
||||
scst_unregister_virtual_dev_driver(&dev->devtype);
|
||||
|
||||
sgv_pool_destroy(dev->pool_clust);
|
||||
sgv_pool_destroy(dev->pool);
|
||||
sgv_pool_del(dev->pool_clust);
|
||||
sgv_pool_del(dev->pool);
|
||||
|
||||
TRACE_DBG("Unregistering finished (dev %p)", dev);
|
||||
|
||||
|
||||
@@ -726,6 +726,8 @@ int scst_get_cmd_abnormal_done_state(const struct scst_cmd *cmd)
|
||||
PRINT_CRIT_ERROR("Wrong cmd state %d (cmd %p, op %x)",
|
||||
cmd->state, cmd, cmd->cdb[0]);
|
||||
sBUG();
|
||||
/* Invalid state to supress compiler's warning */
|
||||
res = SCST_CMD_STATE_LAST_ACTIVE;
|
||||
}
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
|
||||
1050
scst/src/scst_mem.c
1050
scst/src/scst_mem.c
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,6 @@
|
||||
* scst_mem.h
|
||||
*
|
||||
* Copyright (C) 2006 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
|
||||
* Copyright (C) 2007 Krzysztof Blaszkowski <kb@sysmikro.com.pl>
|
||||
* Copyright (C) 2007 - 2009 ID7 Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -36,12 +35,11 @@ struct sgv_pool_obj {
|
||||
/* if <0 - pages, >0 - order */
|
||||
int order_or_pages;
|
||||
|
||||
struct {
|
||||
/* jiffies, protected by pool_mgr_lock */
|
||||
unsigned long time_stamp;
|
||||
struct list_head recycling_list_entry;
|
||||
struct list_head sorted_recycling_list_entry;
|
||||
} recycle_entry;
|
||||
/* jiffies, protected by sgv_pool_lock */
|
||||
unsigned long time_stamp;
|
||||
|
||||
struct list_head recycling_list_entry;
|
||||
struct list_head sorted_recycling_list_entry;
|
||||
|
||||
struct sgv_pool *owner_pool;
|
||||
int orig_sg;
|
||||
@@ -53,13 +51,6 @@ struct sgv_pool_obj {
|
||||
struct scatterlist sg_entries_data[0];
|
||||
};
|
||||
|
||||
struct sgv_pool_acc {
|
||||
u32 cached_pages, cached_entries;
|
||||
atomic_t big_alloc, other_alloc;
|
||||
atomic_t big_pages, other_pages;
|
||||
atomic_t big_merged, other_merged;
|
||||
};
|
||||
|
||||
struct sgv_pool_cache_acc {
|
||||
atomic_t total_alloc, hit_alloc;
|
||||
atomic_t merged;
|
||||
@@ -74,69 +65,49 @@ struct sgv_pool_alloc_fns {
|
||||
|
||||
struct sgv_pool {
|
||||
enum sgv_clustering_types clustering_type;
|
||||
|
||||
struct sgv_pool_alloc_fns alloc_fns;
|
||||
/* 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 */
|
||||
|
||||
/* <=4K, <=8, <=16, <=32, <=64, <=128, <=256, <=512, <=1024, <=2048 */
|
||||
struct kmem_cache *caches[SGV_POOL_ELEMENTS];
|
||||
|
||||
/* protected by pool_mgr_lock */
|
||||
spinlock_t sgv_pool_lock; /* outer lock for sgv_pools_lock! */
|
||||
|
||||
/* Protected by sgv_pool_lock */
|
||||
unsigned int purge_work_scheduled:1;
|
||||
|
||||
/* Protected by sgv_pool_lock */
|
||||
struct list_head sorted_recycling_list;
|
||||
|
||||
int inactive_cached_pages; /* protected by sgv_pool_lock */
|
||||
|
||||
/* Protected by sgv_pool_lock */
|
||||
struct list_head recycling_lists[SGV_POOL_ELEMENTS];
|
||||
|
||||
struct sgv_pool_acc acc;
|
||||
int cached_pages, cached_entries; /* protected by sgv_pool_lock */
|
||||
|
||||
struct sgv_pool_cache_acc cache_acc[SGV_POOL_ELEMENTS];
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20))
|
||||
struct delayed_work sgv_purge_work;
|
||||
#else
|
||||
struct work_struct sgv_purge_work;
|
||||
#endif
|
||||
|
||||
struct list_head sgv_active_pools_list_entry;
|
||||
|
||||
atomic_t big_alloc, big_pages, big_merged;
|
||||
atomic_t other_alloc, other_pages, other_merged;
|
||||
|
||||
atomic_t sgv_pool_ref;
|
||||
|
||||
/* SCST_MAX_NAME + few more bytes to match scst_user expectations */
|
||||
char cache_names[SGV_POOL_ELEMENTS][SCST_MAX_NAME + 10];
|
||||
char name[SCST_MAX_NAME + 10];
|
||||
struct list_head sgv_pool_list_entry;
|
||||
};
|
||||
|
||||
struct scst_sgv_pools_manager {
|
||||
struct {
|
||||
struct sgv_pool norm_clust, norm;
|
||||
struct sgv_pool dma;
|
||||
} default_set;
|
||||
struct mm_struct *owner_mm;
|
||||
|
||||
struct sgv_pool_mgr {
|
||||
spinlock_t pool_mgr_lock;
|
||||
/* protected by pool_mgr_lock */
|
||||
struct list_head sorted_recycling_list;
|
||||
/* protected by pool_mgr_lock */
|
||||
unsigned pitbool_running:1;
|
||||
|
||||
struct sgv_mem_throttling {
|
||||
u32 inactive_pages_total;
|
||||
u32 active_pages_total;
|
||||
|
||||
/*
|
||||
* compared against inactive_pages_total +
|
||||
* active_pages_total
|
||||
*/
|
||||
u32 hi_wmk;
|
||||
/* compared against inactive_pages_total only */
|
||||
u32 lo_wmk;
|
||||
|
||||
u32 releases_on_hiwmk;
|
||||
u32 releases_failed;
|
||||
} throttle; /* protected by pool_mgr_lock */
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23))
|
||||
struct shrinker *sgv_shrinker;
|
||||
#else
|
||||
struct shrinker sgv_shrinker;
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20))
|
||||
struct delayed_work apit_pool;
|
||||
#else
|
||||
struct work_struct apit_pool;
|
||||
#endif
|
||||
} mgr;
|
||||
|
||||
int sgv_max_local_order, sgv_max_trans_order;
|
||||
|
||||
atomic_t sgv_other_total_alloc;
|
||||
struct mutex scst_sgv_pool_mutex;
|
||||
struct list_head scst_sgv_pool_list;
|
||||
struct list_head sgv_pools_list_entry;
|
||||
};
|
||||
|
||||
int sgv_pool_init(struct sgv_pool *pool, const char *name,
|
||||
@@ -151,7 +122,7 @@ static inline struct scatterlist *sgv_pool_sg(struct sgv_pool_obj *obj)
|
||||
extern int scst_sgv_pools_init(unsigned long mem_hwmark,
|
||||
unsigned long mem_lwmark);
|
||||
extern void scst_sgv_pools_deinit(void);
|
||||
extern int sgv_pool_procinfo_show(struct seq_file *seq, void *v);
|
||||
extern int sgv_procinfo_show(struct seq_file *seq, void *v);
|
||||
|
||||
void scst_sgv_pool_use_norm(struct scst_tgt_dev *tgt_dev);
|
||||
void scst_sgv_pool_use_norm_clust(struct scst_tgt_dev *tgt_dev);
|
||||
|
||||
@@ -1918,7 +1918,7 @@ static struct scst_proc_data scst_sessions_proc_data = {
|
||||
|
||||
static struct scst_proc_data scst_sgv_proc_data = {
|
||||
SCST_DEF_RW_SEQ_OP(NULL)
|
||||
.show = sgv_pool_procinfo_show,
|
||||
.show = sgv_procinfo_show,
|
||||
};
|
||||
|
||||
static int scst_groups_names_show(struct seq_file *seq, void *v)
|
||||
|
||||
@@ -2924,7 +2924,8 @@ static int scst_pre_xmit_response(struct scst_cmd *cmd)
|
||||
scst_xmit_process_aborted_cmd(cmd);
|
||||
else if (unlikely(cmd->status == SAM_STAT_CHECK_CONDITION) &&
|
||||
SCST_SENSE_VALID(cmd->sense) &&
|
||||
!test_bit(SCST_CMD_NO_RESP, &cmd->cmd_flags)) {
|
||||
!test_bit(SCST_CMD_NO_RESP, &cmd->cmd_flags) &&
|
||||
(cmd->tgt_dev != NULL)) {
|
||||
struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
|
||||
|
||||
TRACE_DBG("Storing sense (cmd %p)", cmd);
|
||||
|
||||
Reference in New Issue
Block a user