From c8a47b0753968674e8f253c387856d75451c8989 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Mon, 22 Jan 2007 10:38:18 +0000 Subject: [PATCH] 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 --- scst/ChangeLog | 2 +- scst/src/scst_lib.c | 5 +++-- scst/src/scst_mem.c | 9 +++++---- scst/src/scst_mem.h | 3 ++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/scst/ChangeLog b/scst/ChangeLog index 702bec672..ca193267c 100644 --- a/scst/ChangeLog +++ b/scst/ChangeLog @@ -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 --------------------------------------------------- diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 13ae80626..676744d8d 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -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) diff --git a/scst/src/scst_mem.c b/scst/src/scst_mem.c index cb8b306d6..c6f52ee93 100644 --- a/scst/src/scst_mem.c +++ b/scst/src/scst_mem.c @@ -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]); diff --git a/scst/src/scst_mem.h b/scst/src/scst_mem.h index f40cbe3f8..a2a3eef77 100644 --- a/scst/src/scst_mem.h +++ b/scst/src/scst_mem.h @@ -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);