2007-02-07 03:30:22

by Sumant Patro

[permalink] [raw]
Subject: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing

Preallocate memory for ioctl processing. This is to avoid situations
where ioctl fails for lack of memory (when system under heavy stress).
The memory pool will have 8*4K, 4*8K and 1*64K memory chunks

Signed-off-by: Sumant Patro <[email protected]>

drivers/scsi/megaraid/megaraid_sas.c | 257 ++++++++++++++++++++++++-
drivers/scsi/megaraid/megaraid_sas.h | 32 ++-
2 files changed, 276 insertions(+), 13 deletions(-)

diff -uprN 2.6.new-p3/drivers/scsi/megaraid/megaraid_sas.c 2.6.new-p4/drivers/scsi/megaraid/megaraid_sas.c
--- 2.6.new-p3/drivers/scsi/megaraid/megaraid_sas.c 2007-02-06 08:50:40.000000000 -0800
+++ 2.6.new-p4/drivers/scsi/megaraid/megaraid_sas.c 2007-02-06 13:12:42.000000000 -0800
@@ -74,6 +74,14 @@ static DEFINE_MUTEX(megasas_async_queue_

static u32 megasas_dbg_lvl;

+/* For IOCTL mem pool */
+int arr[MAX_IOCTL_MEM_POOL] = {MAX_4K_BUFF,MAX_8K_BUFF,MAX_64K_BUFF};
+
+int arr_size[MAX_IOCTL_MEM_POOL] =
+ {MEGASAS_INIT_IOCTL_MEM_SIZE/* 4k */,
+ 2*MEGASAS_INIT_IOCTL_MEM_SIZE/* 8k */,
+ 16*MEGASAS_INIT_IOCTL_MEM_SIZE/* 64k */};
+
/**
* megasas_get_cmd - Get a command from the free pool
* @instance: Adapter soft state
@@ -1805,6 +1813,194 @@ megasas_get_ctrl_info(struct megasas_ins
}

/**
+ * megasas_get_ioctl_mem - Get a buff from the free ioctl memory pool
+ * @instance: Adapter soft state
+ * @i: mem pool index
+ *
+ * Returns a free buff from the pool
+ */
+static inline struct megasas_ioctl_mm *
+megasas_get_ioctl_mem(struct megasas_instance* instance, u8 i)
+{
+ unsigned long flags;
+ struct megasas_ioctl_mm *ioctl_mm = NULL;
+
+ if(i >= MAX_IOCTL_MEM_POOL)
+ goto out;
+
+ spin_lock_irqsave(&instance->ioctl_memory_pool_lock, flags);
+
+ if (!list_empty(&instance->ioctl_memory_pool[i])) {
+ ioctl_mm = list_entry((&instance->ioctl_memory_pool[i])->next,
+ struct megasas_ioctl_mm, list);
+ list_del_init(&ioctl_mm->list);
+ } else
+ printk(KERN_DEBUG "megasas: ioctl memory pool empty!\n");
+
+ spin_unlock_irqrestore(&instance->ioctl_memory_pool_lock, flags);
+out:
+ return ioctl_mm;
+}
+
+/**
+ * megasas_return_ioctl_mm - Return memory to ioctl memory pool
+ * @instance: Adapter soft state
+ * @megasas_ioctl_mm: ioctl mem block
+ * @i: mem_pool_index
+ */
+static inline void
+megasas_return_ioctl_mem(struct megasas_instance *instance,
+ struct megasas_ioctl_mm *ioctl_mm, u8 i)
+{
+ unsigned long flags;
+ if(!ioctl_mm){
+ printk(KERN_DEBUG "megasas: Trying to return "
+ "NULL to mem_pool\n");
+ return;
+ }
+ spin_lock_irqsave(&instance->ioctl_memory_pool_lock, flags);
+ list_add_tail(&ioctl_mm->list, &instance->ioctl_memory_pool[i]);
+ spin_unlock_irqrestore(&instance->ioctl_memory_pool_lock, flags);
+}
+
+/**
+ * megasas_free_ioctl_mem_pools - Free all the memory in the ioctl memory pool
+ * @instance: Adapter soft state
+ */
+static void
+megasas_free_ioctl_mem_pools(struct megasas_instance *instance)
+{
+ struct megasas_ioctl_mm *ioctl_mm;
+ u32 i,j;
+ u32 mem_size;
+ if(instance->mem_pool_empty)
+ return;
+ for (i=0; i < MAX_IOCTL_MEM_POOL; i++) {
+ mem_size = arr_size[i];
+ for (j = 0; j < arr[i]; j++) {
+ ioctl_mm = megasas_get_ioctl_mem(instance, i);
+
+ if (ioctl_mm){
+ if(ioctl_mm->vaddr)
+ pci_free_consistent(instance->pdev,
+ mem_size,
+ ioctl_mm->vaddr,
+ ioctl_mm->buf_handle);
+ kfree(ioctl_mm);
+ }
+ }
+ }
+}
+
+/**
+ * megasas_setup_mem_pools - Setup memory in the ioctl memory pool
+ * @instance: Adapter soft state
+ *
+ * The memory pool will have 8x4K, 4*8K and 1x64K memory
+ * ioctl_memory_pool[0] ----> 4k memory list
+ * ioctl_memory_pool[1] ----> 8K memory list
+ * ioctl_memory_pool[2] ----> 64K memory list
+ */
+
+static int
+megasas_setup_mem_pools(struct megasas_instance *instance)
+{
+ struct megasas_ioctl_mm *ioctl_mm;
+ dma_addr_t buf_handle;
+ void *vaddr;
+ u32 i, j;
+ u32 mem_size;
+ for (i=0; i < MAX_IOCTL_MEM_POOL; i++) {
+ mem_size = arr_size[i];
+
+ for (j = 0; j < arr[i]; j++) {
+
+ ioctl_mm = kmalloc(sizeof(struct megasas_ioctl_mm), GFP_KERNEL);
+ if(!ioctl_mm){
+ printk(KERN_DEBUG "megasas:Failed to alloc "
+ "init memory for ioctl \n");
+ goto failed_to_alloc_mem_ioctl;
+ }
+ vaddr = pci_alloc_consistent(instance->pdev,mem_size,
+ &buf_handle);
+ if (!vaddr) {
+ printk(KERN_DEBUG "megasas:Failed to alloc "
+ "memory for ioctl \n");
+ goto failed_to_alloc_mem_ioctl;
+ } else {
+ ioctl_mm->vaddr = vaddr;
+ ioctl_mm->buf_handle = (u32)buf_handle;
+
+ list_add_tail(&ioctl_mm->list,
+ &instance->ioctl_memory_pool[i]);
+ }
+ }
+ }
+ return 0;
+failed_to_alloc_mem_ioctl:
+ megasas_free_ioctl_mem_pools(instance);
+ return 1;
+}
+
+/**
+ * megasas_get_buff_for_sge - Free all the memory in the ioctl memory pool
+ * @instance: Adapter soft state
+ * @cmd: megasas_cmd
+ */
+
+int
+megasas_get_buff_for_sge(struct megasas_iocpacket *ioc,
+ struct megasas_instance *instance,
+ struct megasas_cmd *cmd)
+{
+ int i,n;
+ u8 mem_type;
+ struct megasas_ioctl_mm* ioctl_mm;
+ if(instance->mem_pool_empty)
+ goto empty;
+ for (i = 0; i < ioc->sge_count; i++) {
+ /*
+ * Check if we have buffer to use from our mem_pool
+ * If we donot have enough to satisfy for all sge's then
+ * free that has already been attached to the ioc
+ */
+ mem_type=0xff;
+ if (ioc->sgl[i].iov_len <= MEGASAS_INIT_IOCTL_MEM_SIZE)
+ mem_type=0;
+ else if ((ioc->sgl[i].iov_len > MEGASAS_INIT_IOCTL_MEM_SIZE) &&
+ (ioc->sgl[i].iov_len <= 2*MEGASAS_INIT_IOCTL_MEM_SIZE))
+ mem_type=1;
+ else if ((ioc->sgl[i].iov_len > 2*MEGASAS_INIT_IOCTL_MEM_SIZE) &&
+ (ioc->sgl[i].iov_len <= 16*MEGASAS_INIT_IOCTL_MEM_SIZE))
+ mem_type=2;
+
+ ioctl_mm = megasas_get_ioctl_mem(instance, mem_type);
+
+ if (ioctl_mm) {
+ cmd->ioctl_mem[i]=ioctl_mm;
+ cmd->ioctl_mem_pool_index[i] = mem_type;
+ } else
+ /* Not enough buffer in mem pool
+ * Free all allocated buffer for this ioc
+ */
+ goto out;
+ }
+ return 0;
+out:
+ for (n = 0; n < i; n++) {
+ if ((struct megasas_ioctl_mm *)cmd->ioctl_mem[i]) {
+ megasas_return_ioctl_mem(instance,
+ (struct megasas_ioctl_mm *)cmd->ioctl_mem[i],
+ cmd->ioctl_mem_pool_index[i]);
+ cmd->ioctl_mem[i]=NULL;
+ cmd->ioctl_mem_pool_index[i] = 0xff;
+ }
+ }
+empty:
+ return 1;
+}
+
+/**
* megasas_complete_cmd_dpc - Returns FW's controller structure
* @instance_addr: Address of adapter soft state
*
@@ -2310,7 +2506,7 @@ static int megasas_io_attach(struct mega
static int __devinit
megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
- int rval;
+ int rval,i;
struct Scsi_Host *host;
struct megasas_instance *instance;

@@ -2396,10 +2592,23 @@ megasas_probe_one(struct pci_dev *pdev,
init_waitqueue_head(&instance->abort_cmd_wait_q);

spin_lock_init(&instance->cmd_pool_lock);
+ spin_lock_init(&instance->ioctl_memory_pool_lock);

sema_init(&instance->aen_mutex, 1);
sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);

+ /*
+ * for-ioctl: initialize ioctl memory list
+ */
+ for (i=0; i<MAX_IOCTL_MEM_POOL; i++) {
+ INIT_LIST_HEAD(&instance->ioctl_memory_pool[i]);
+ }
+
+ if(megasas_setup_mem_pools(instance))
+ instance->mem_pool_empty=1;
+
+ /* end for-ioctl */
+
/*
* Initialize PCI related and misc parameters
*/
@@ -2472,6 +2681,8 @@ megasas_probe_one(struct pci_dev *pdev,
fail_irq:
fail_init_mfi:
fail_alloc_dma_buf:
+ /* Free ioctl mem pool */
+ megasas_free_ioctl_mem_pools(instance);
if (instance->evt_detail)
pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
instance->evt_detail,
@@ -2600,6 +2811,9 @@ static void megasas_detach_one(struct pc
free_irq(instance->pdev->irq, instance);

megasas_release_mfi(instance);
+ /* Free IOCTL mem pool */
+ megasas_free_ioctl_mem_pools(instance);
+

pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
instance->evt_detail, instance->evt_detail_h);
@@ -2699,6 +2913,7 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
void *sense = NULL;
dma_addr_t sense_handle;
u32 *sense_ptr;
+ u8 from_pool = 0;

memset(kbuff_arr, 0, sizeof(kbuff_arr));

@@ -2734,18 +2949,30 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
kern_sge32 = (struct megasas_sge32 *)
((unsigned long)cmd->frame + ioc->sgl_off);

+ /*
+ * Check if we have buffer to use from our ioctl mem_pool
+ * If we donot have then try to allocate new buffer
+ */
+ if(!megasas_get_buff_for_sge(ioc,instance,cmd))
+ from_pool = 1;
+
/*
* For each user buffer, create a mirror buffer and copy in
*/
for (i = 0; i < ioc->sge_count; i++) {
- kbuff_arr[i] = pci_alloc_consistent(instance->pdev,
+ if (from_pool) {
+ kbuff_arr[i] = cmd->ioctl_mem[i]->vaddr;
+ buf_handle = cmd->ioctl_mem[i]->buf_handle;
+ } else {
+ kbuff_arr[i] = pci_alloc_consistent(instance->pdev,
ioc->sgl[i].iov_len,
&buf_handle);
- if (!kbuff_arr[i]) {
- printk(KERN_DEBUG "megasas: Failed to alloc "
- "kernel SGL buffer for IOCTL \n");
- error = -ENOMEM;
- goto out;
+ if (!kbuff_arr[i]) {
+ printk(KERN_DEBUG "megasas: Failed to alloc "
+ "kernel SGL buffer for IOCTL \n");
+ error = -ENOMEM;
+ goto out;
+ }
}

/*
@@ -2832,9 +3059,19 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
}

for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) {
- pci_free_consistent(instance->pdev,
- kern_sge32[i].length,
- kbuff_arr[i], kern_sge32[i].phys_addr);
+ if (from_pool) {
+ /* Return to the mem pool */
+ if ((struct megasas_ioctl_mm *)cmd->ioctl_mem[i]) {
+ megasas_return_ioctl_mem(instance,
+ (struct megasas_ioctl_mm *)cmd->ioctl_mem[i],
+ cmd->ioctl_mem_pool_index[i]);
+ cmd->ioctl_mem_pool_index[i]=0xff;
+ cmd->ioctl_mem[i]=NULL;
+ }
+ } else
+ pci_free_consistent(instance->pdev,
+ kern_sge32[i].length,
+ kbuff_arr[i], kern_sge32[i].phys_addr);
}

megasas_return_cmd(instance, cmd);
diff -uprN 2.6.new-p3/drivers/scsi/megaraid/megaraid_sas.h 2.6.new-p4/drivers/scsi/megaraid/megaraid_sas.h
--- 2.6.new-p3/drivers/scsi/megaraid/megaraid_sas.h 2007-02-06 08:51:23.000000000 -0800
+++ 2.6.new-p4/drivers/scsi/megaraid/megaraid_sas.h 2007-02-06 10:14:17.000000000 -0800
@@ -539,6 +539,17 @@ struct megasas_ctrl_info {

#define MEGASAS_DBG_LVL 1

+/*
+ * For ioctl memory manager
+ */
+
+#define MAX_IOCTL_MEM_POOL 3
+#define MEGASAS_INIT_IOCTL_MEM_SIZE 4096
+#define MAX_IOCTL_MEM_BLOCK 16
+#define MAX_4K_BUFF 8
+#define MAX_8K_BUFF 4
+#define MAX_64K_BUFF 1
+
/*
* When SCSI mid-layer calls driver's reset routine, driver waits for
* MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
@@ -1059,6 +1070,12 @@ struct megasas_evt_detail {
u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
};

+struct megasas_ioctl_mm {
+ void *vaddr;
+ dma_addr_t buf_handle;
+ struct list_head list;
+};
+
struct megasas_instance {

u32 *producer;
@@ -1085,6 +1102,12 @@ struct megasas_instance {
struct dma_pool *frame_dma_pool;
struct dma_pool *sense_dma_pool;

+ /* ioctl memory */
+ struct list_head ioctl_memory_pool[MAX_IOCTL_MEM_POOL];
+ spinlock_t ioctl_memory_pool_lock;
+ u8 mem_pool_empty;
+ /* end :ioctl memory */
+
struct megasas_evt_detail *evt_detail;
dma_addr_t evt_detail_h;
struct megasas_cmd *aen_cmd;
@@ -1116,6 +1139,9 @@ struct megasas_instance {
((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \
scp->device->id

+#define MAX_MGMT_ADAPTERS 1024
+#define MAX_IOCTL_SGE 16
+
struct megasas_cmd {

union megasas_frame *frame;
@@ -1132,10 +1158,10 @@ struct megasas_cmd {
struct scsi_cmnd *scmd;
struct megasas_instance *instance;
u32 frame_count;
-};

-#define MAX_MGMT_ADAPTERS 1024
-#define MAX_IOCTL_SGE 16
+ u8 ioctl_mem_pool_index[MAX_IOCTL_SGE]; /*0xff for not in use*/
+ struct megasas_ioctl_mm *ioctl_mem[MAX_IOCTL_SGE];
+};

struct megasas_iocpacket {



Attachments:
p4-ioctl_mm.patch (11.29 kB)

2007-02-07 21:30:29

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing

On Tue, 06 Feb 2007 14:19:54 -0800
Sumant Patro <[email protected]> wrote:

> Preallocate memory for ioctl processing. This is to avoid situations
> where ioctl fails for lack of memory (when system under heavy stress).
> The memory pool will have 8*4K, 4*8K and 1*64K memory chunks

mutter.

I suspect all this horror is due to stupidity in the DMA API.

pci_alloc_consistent() just goes and assumes GFP_ATOMIC, whereas
the caller (megasas_mgmt_fw_ioctl) would have been perfectly happy
to use GFP_KERNEL.

I bet this fixes it:



diff -puN include/asm-generic/pci-dma-compat.h~a include/asm-generic/pci-dma-compat.h
--- a/include/asm-generic/pci-dma-compat.h~a
+++ a/include/asm-generic/pci-dma-compat.h
@@ -4,6 +4,7 @@
#ifndef _ASM_GENERIC_PCI_DMA_COMPAT_H
#define _ASM_GENERIC_PCI_DMA_COMPAT_H

+#include <linux/types.h>
#include <linux/dma-mapping.h>

/* note pci_set_dma_mask isn't here, since it's a public function
@@ -22,6 +23,13 @@ pci_alloc_consistent(struct pci_dev *hwd
return dma_alloc_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, dma_handle, GFP_ATOMIC);
}

+static inline void *
+pci_alloc_consistent_not_stupid(struct pci_dev *hwdev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flags)
+{
+ return dma_alloc_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, dma_handle, flags);
+}
+
static inline void
pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
diff -puN drivers/scsi/megaraid/megaraid_sas.c~a drivers/scsi/megaraid/megaraid_sas.c
--- a/drivers/scsi/megaraid/megaraid_sas.c~a
+++ a/drivers/scsi/megaraid/megaraid_sas.c
@@ -2655,9 +2655,9 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
* For each user buffer, create a mirror buffer and copy in
*/
for (i = 0; i < ioc->sge_count; i++) {
- kbuff_arr[i] = pci_alloc_consistent(instance->pdev,
+ kbuff_arr[i] = pci_alloc_consistent_not_stupid(instance->pdev,
ioc->sgl[i].iov_len,
- &buf_handle);
+ &buf_handle, GFP_KERNEL);
if (!kbuff_arr[i]) {
printk(KERN_DEBUG "megasas: Failed to alloc "
"kernel SGL buffer for IOCTL \n");
@@ -2684,8 +2684,9 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
}

if (ioc->sense_len) {
- sense = pci_alloc_consistent(instance->pdev, ioc->sense_len,
- &sense_handle);
+ sense = pci_alloc_consistent_nopt_stupid(instance->pdev,
+ ioc->sense_len, &sense_handle,
+ GFP_KERNEL);
if (!sense) {
error = -ENOMEM;
goto out;
_

2007-02-07 22:02:23

by James Bottomley

[permalink] [raw]
Subject: Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing

On Wed, 2007-02-07 at 13:30 -0800, Andrew Morton wrote:
> I suspect all this horror is due to stupidity in the DMA API.
>
> pci_alloc_consistent() just goes and assumes GFP_ATOMIC, whereas
> the caller (megasas_mgmt_fw_ioctl) would have been perfectly happy
> to use GFP_KERNEL.
>
> I bet this fixes it

It does, but the DMA API was expanded to cope with this exact case, so
use dma_alloc_coherent() directly in the megaraid code instead. The dev
is just &pci_dev->dev.

James


2007-02-08 19:38:35

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing

On Wed, Feb 07, 2007 at 01:30:20PM -0800, Andrew Morton wrote:
> On Tue, 06 Feb 2007 14:19:54 -0800
> Sumant Patro <[email protected]> wrote:
>
> > Preallocate memory for ioctl processing. This is to avoid situations
> > where ioctl fails for lack of memory (when system under heavy stress).
> > The memory pool will have 8*4K, 4*8K and 1*64K memory chunks
>
> mutter.
>
> I suspect all this horror is due to stupidity in the DMA API.
>
> pci_alloc_consistent() just goes and assumes GFP_ATOMIC, whereas
> the caller (megasas_mgmt_fw_ioctl) would have been perfectly happy
> to use GFP_KERNEL.
>
> I bet this fixes it:

but it's ugly as hell, why there is a much more trivial fix for it:
simply use dma_alloc_coherent.

2008-10-16 01:07:18

by CaT

[permalink] [raw]
Subject: Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing

With hope that resurrecting a 1.5yr old thread is not a wrong thing to
do...

On Wed, Feb 07, 2007 at 05:02:13PM -0500, James Bottomley wrote:
> On Wed, 2007-02-07 at 13:30 -0800, Andrew Morton wrote:
> > I suspect all this horror is due to stupidity in the DMA API.
> >
> > pci_alloc_consistent() just goes and assumes GFP_ATOMIC, whereas
> > the caller (megasas_mgmt_fw_ioctl) would have been perfectly happy
> > to use GFP_KERNEL.
> >
> > I bet this fixes it
>
> It does, but the DMA API was expanded to cope with this exact case, so
> use dma_alloc_coherent() directly in the megaraid code instead. The dev
> is just &pci_dev->dev.

I'm wondering if this was meant to lay this issue to rest. The reason
being that I just got this error last night during a period of high disk
and network IO (there was an over-the-network backup happening). dmesg
gives:

MegaCli: page allocation failure. order:0, mode:0x10d4

Call Trace:
[<ffffffff80232c55>] printk_ratelimit+0x15/0x20
[<ffffffff8026306f>] __alloc_pages+0x2ff/0x320
[<ffffffff80212920>] dma_alloc_pages+0x20/0x90
[<ffffffff80212a29>] dma_alloc_coherent+0x99/0x200
[<ffffffff8043b859>] megasas_mgmt_ioctl_fw+0x1c9/0x450
[<ffffffff8043bce8>] megasas_mgmt_ioctl+0x28/0x40
[<ffffffff8028eff1>] do_ioctl+0x31/0x90
[<ffffffff8028f0c3>] vfs_ioctl+0x73/0x2d0
[<ffffffff8028f36a>] sys_ioctl+0x4a/0x80
[<ffffffff8020bb3e>] system_call+0x7e/0x83

Mem-info:
DMA per-cpu:
CPU 0: Hot: hi: 0, btch: 1 usd: 0 Cold: hi: 0, btch: 1 usd: 0
CPU 1: Hot: hi: 0, btch: 1 usd: 0 Cold: hi: 0, btch: 1 usd: 0
DMA32 per-cpu:
CPU 0: Hot: hi: 186, btch: 31 usd: 128 Cold: hi: 62, btch: 15 usd: 14
CPU 1: Hot: hi: 186, btch: 31 usd: 183 Cold: hi: 62, btch: 15 usd: 59
Active:322989 inactive:1073 dirty:168 writeback:7 unstable:0
free:3894 slab:171815 mapped:3457 pagetables:4277 bounce:0
DMA free:6788kB min:16kB low:20kB high:24kB active:0kB inactive:0kB present:6148kB pages_scanned:0 all_unreclaimable? yes
lowmem_reserve[]: 0 1988 1988 1988
DMA32 free:8788kB min:5692kB low:7112kB high:8536kB active:1291956kB inactive:4292kB present:2035720kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 0 0
DMA: 3*4kB 5*8kB 3*16kB 1*32kB 4*64kB 2*128kB 2*256kB 1*512kB 1*1024kB 0*2048kB 1*4096kB = 6788kB
DMA32: 804*4kB 19*8kB 34*16kB 37*32kB 0*64kB 1*128kB 0*256kB 1*512kB 1*1024kB 1*2048kB 0*4096kB = 8808kB
Swap cache: add 132711, delete 132711, find 496226/496957, race 0+0
Free swap = 979400kB
Total swap = 979924kB
Free swap: 979400kB
524200 pages of RAM
14486 reserved pages
93705 pages shared
0 pages swap cached
megasas: Failed to alloc kernel SGL buffer for IOCTL
MegaCli[18889]: segfault at 0000000000000000 rip 00000000004ab9b5 rsp 00007fff48802c30 error 4

I was attempting to get the state of the raid array (monitoring for downed
drives, etc) with MegaCLI 2.00.11. This is with kernel 2.6.23.16.

--
"Police noticed some rustling sounds from Linn's bottom area
and on closer inspection a roll of cash was found protruding
from Linn's anus, the full amount of cash taken in the robbery."
- http://www.smh.com.au/news/world/robber-hides-loot-up-his-booty/2008/05/09/1210131248617.html

2008-10-16 13:54:36

by Yang, Bo

[permalink] [raw]
Subject: RE: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing

What MegaCli cmds did you using (DCMD or DCDB?).

Thanks,

Bo Yang

-----Original Message-----
From: CaT [mailto:[email protected]]
Sent: Wednesday, October 15, 2008 8:17 PM
To: James Bottomley
Cc: Andrew Morton; Patro, Sumant; [email protected]; [email protected]; Kolli, Neela; Yang, Bo; Patro, Sumant
Subject: Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing

With hope that resurrecting a 1.5yr old thread is not a wrong thing to
do...

On Wed, Feb 07, 2007 at 05:02:13PM -0500, James Bottomley wrote:
> On Wed, 2007-02-07 at 13:30 -0800, Andrew Morton wrote:
> > I suspect all this horror is due to stupidity in the DMA API.
> >
> > pci_alloc_consistent() just goes and assumes GFP_ATOMIC, whereas
> > the caller (megasas_mgmt_fw_ioctl) would have been perfectly happy
> > to use GFP_KERNEL.
> >
> > I bet this fixes it
>
> It does, but the DMA API was expanded to cope with this exact case, so
> use dma_alloc_coherent() directly in the megaraid code instead. The dev
> is just &pci_dev->dev.

I'm wondering if this was meant to lay this issue to rest. The reason
being that I just got this error last night during a period of high disk
and network IO (there was an over-the-network backup happening). dmesg
gives:

MegaCli: page allocation failure. order:0, mode:0x10d4

Call Trace:
[<ffffffff80232c55>] printk_ratelimit+0x15/0x20
[<ffffffff8026306f>] __alloc_pages+0x2ff/0x320
[<ffffffff80212920>] dma_alloc_pages+0x20/0x90
[<ffffffff80212a29>] dma_alloc_coherent+0x99/0x200
[<ffffffff8043b859>] megasas_mgmt_ioctl_fw+0x1c9/0x450
[<ffffffff8043bce8>] megasas_mgmt_ioctl+0x28/0x40
[<ffffffff8028eff1>] do_ioctl+0x31/0x90
[<ffffffff8028f0c3>] vfs_ioctl+0x73/0x2d0
[<ffffffff8028f36a>] sys_ioctl+0x4a/0x80
[<ffffffff8020bb3e>] system_call+0x7e/0x83

Mem-info:
DMA per-cpu:
CPU 0: Hot: hi: 0, btch: 1 usd: 0 Cold: hi: 0, btch: 1 usd: 0
CPU 1: Hot: hi: 0, btch: 1 usd: 0 Cold: hi: 0, btch: 1 usd: 0
DMA32 per-cpu:
CPU 0: Hot: hi: 186, btch: 31 usd: 128 Cold: hi: 62, btch: 15 usd: 14
CPU 1: Hot: hi: 186, btch: 31 usd: 183 Cold: hi: 62, btch: 15 usd: 59
Active:322989 inactive:1073 dirty:168 writeback:7 unstable:0
free:3894 slab:171815 mapped:3457 pagetables:4277 bounce:0
DMA free:6788kB min:16kB low:20kB high:24kB active:0kB inactive:0kB present:6148kB pages_scanned:0 all_unreclaimable? yes
lowmem_reserve[]: 0 1988 1988 1988
DMA32 free:8788kB min:5692kB low:7112kB high:8536kB active:1291956kB inactive:4292kB present:2035720kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 0 0
DMA: 3*4kB 5*8kB 3*16kB 1*32kB 4*64kB 2*128kB 2*256kB 1*512kB 1*1024kB 0*2048kB 1*4096kB = 6788kB
DMA32: 804*4kB 19*8kB 34*16kB 37*32kB 0*64kB 1*128kB 0*256kB 1*512kB 1*1024kB 1*2048kB 0*4096kB = 8808kB
Swap cache: add 132711, delete 132711, find 496226/496957, race 0+0
Free swap = 979400kB
Total swap = 979924kB
Free swap: 979400kB
524200 pages of RAM
14486 reserved pages
93705 pages shared
0 pages swap cached
megasas: Failed to alloc kernel SGL buffer for IOCTL
MegaCli[18889]: segfault at 0000000000000000 rip 00000000004ab9b5 rsp 00007fff48802c30 error 4

I was attempting to get the state of the raid array (monitoring for downed
drives, etc) with MegaCLI 2.00.11. This is with kernel 2.6.23.16.

--
"Police noticed some rustling sounds from Linn's bottom area
and on closer inspection a roll of cash was found protruding
from Linn's anus, the full amount of cash taken in the robbery."
- http://www.smh.com.au/news/world/robber-hides-loot-up-his-booty/2008/05/09/1210131248617.html

2008-10-16 22:37:18

by CaT

[permalink] [raw]
Subject: Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing

On Thu, Oct 16, 2008 at 07:54:07AM -0600, Yang, Bo wrote:
> What MegaCli cmds did you using (DCMD or DCDB?).

MegaCli -LdPdInfo -a0 -NoLog

Forgot to mention that this is the 64bit version of the command.

--
"Police noticed some rustling sounds from Linn's bottom area
and on closer inspection a roll of cash was found protruding
from Linn's anus, the full amount of cash taken in the robbery."
- http://www.smh.com.au/news/world/robber-hides-loot-up-his-booty/2008/05/09/1210131248617.html