Bugfix for Fedora 6 kernel where GFP_ATOMIC constant is redefined, which lead to massive commands data

buffers memory allocations failures.


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@83 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2007-01-22 10:38:18 +00:00
parent cebd38b37e
commit c8a47b0753
4 changed files with 11 additions and 8 deletions

View File

@@ -13,7 +13,7 @@ Summary of changes between versions 0.9.5 and 0.9.6
- Support for CPU cache flushing before doing DMA to target devices added.
- Various cleanups and bug fixes.
- Various cleanups, bug fixes and improvements.
Summary of changes between versions 0.9.4 and 0.9.5
---------------------------------------------------

View File

@@ -1313,6 +1313,7 @@ int scst_alloc_space(struct scst_cmd *cmd)
int ini_unchecked_isa_dma, ini_use_clustering;
int use_clustering = 0;
struct sgv_pool *pool;
int atomic = scst_cmd_atomic(cmd);
TRACE_ENTRY();
@@ -1324,7 +1325,7 @@ int scst_alloc_space(struct scst_cmd *cmd)
}
gfp_mask = __GFP_NOWARN;
gfp_mask |= (scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
gfp_mask |= (atomic ? GFP_ATOMIC : GFP_KERNEL);
pool = &scst_sgv.norm;
if (cmd->dev->scsi_dev != NULL) {
@@ -1364,7 +1365,7 @@ int scst_alloc_space(struct scst_cmd *cmd)
cmd->sg = scst_alloc(cmd->bufflen, gfp_mask, use_clustering,
&cmd->sg_cnt);
} else {
cmd->sg = sgv_pool_alloc(pool, cmd->bufflen, gfp_mask,
cmd->sg = sgv_pool_alloc(pool, cmd->bufflen, gfp_mask, atomic,
&cmd->sg_cnt, &cmd->sgv);
}
if (cmd->sg == NULL)

View File

@@ -211,7 +211,8 @@ out_no_mem:
}
struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, int size,
unsigned long gfp_mask, int *count, struct sgv_pool_obj **sgv)
unsigned long gfp_mask, int atomic, int *count,
struct sgv_pool_obj **sgv)
{
struct sgv_pool_obj *obj;
int order, pages, cnt, sg;
@@ -227,7 +228,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, int size,
if (order >= SGV_POOL_ELEMENTS) {
obj = NULL;
if (gfp_mask & GFP_ATOMIC)
if (atomic)
goto out;
atomic_inc(&sgv_big_total_alloc);
atomic_dec(&sgv_other_total_alloc);
@@ -238,7 +239,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, int size,
obj = kmem_cache_alloc(pool->caches[order],
gfp_mask & ~(__GFP_HIGHMEM|GFP_DMA));
if (obj == NULL) {
if (!(gfp_mask & GFP_ATOMIC)) {
if (!atomic) {
TRACE(TRACE_OUT_OF_MEM, "Allocation of sgv_pool_obj "
"failed (size %d)", size);
}
@@ -248,7 +249,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, int size,
if (obj->owner_cache != pool->caches[order]) {
int esz, epg, eorder;
if (gfp_mask & GFP_ATOMIC)
if (atomic)
goto out_free;
esz = (1 << order) * sizeof(obj->entries[0]);

View File

@@ -80,7 +80,8 @@ extern int sgv_pool_init(struct sgv_pool *pool, const char *name,
extern void sgv_pool_deinit(struct sgv_pool *pool);
extern struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, int size,
unsigned long gfp_mask, int *count, struct sgv_pool_obj **sgv);
unsigned long gfp_mask, int atomic, int *count,
struct sgv_pool_obj **sgv);
static inline void sgv_pool_free(struct sgv_pool_obj *sgv)
{
TRACE_MEM("Freeing sgv_obj %p", sgv);