- 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:
Vladislav Bolkhovitin
2009-05-11 17:30:47 +00:00
parent 1a390f63de
commit e061263995
9 changed files with 715 additions and 479 deletions

View File

@@ -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];

View File

@@ -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 */

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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);

File diff suppressed because it is too large Load Diff

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);