All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing
@ 2007-02-06 22:19 Sumant Patro
  2007-02-07 21:30 ` Andrew Morton
  0 siblings, 1 reply; 8+ messages in thread
From: Sumant Patro @ 2007-02-06 22:19 UTC (permalink / raw)
  To: James.Bottomley, akpm, linux-scsi
  Cc: linux-kernel, neela.kolli, bo.yang, sumant.patro

[-- Attachment #1: Type: text/plain, Size: 11990 bytes --]

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 <sumant.patro@lsi.com>

 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 {
 


[-- Attachment #2: p4-ioctl_mm.patch --]
[-- Type: text/x-patch, Size: 11560 bytes --]

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 {
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing
  2007-02-06 22:19 [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing Sumant Patro
@ 2007-02-07 21:30 ` Andrew Morton
  2007-02-07 22:02   ` James Bottomley
  2007-02-08 19:38   ` Christoph Hellwig
  0 siblings, 2 replies; 8+ messages in thread
From: Andrew Morton @ 2007-02-07 21:30 UTC (permalink / raw)
  To: Sumant Patro
  Cc: James.Bottomley, linux-scsi, linux-kernel, neela.kolli, bo.yang,
	sumant.patro

On Tue, 06 Feb 2007 14:19:54 -0800
Sumant Patro <sumantp@lsil.com> 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;
_


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing
  2007-02-07 21:30 ` Andrew Morton
@ 2007-02-07 22:02   ` James Bottomley
  2008-10-16  0:17     ` CaT
  2007-02-08 19:38   ` Christoph Hellwig
  1 sibling, 1 reply; 8+ messages in thread
From: James Bottomley @ 2007-02-07 22:02 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Sumant Patro, linux-scsi, linux-kernel, neela.kolli, bo.yang,
	sumant.patro

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



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing
  2007-02-07 21:30 ` Andrew Morton
  2007-02-07 22:02   ` James Bottomley
@ 2007-02-08 19:38   ` Christoph Hellwig
  1 sibling, 0 replies; 8+ messages in thread
From: Christoph Hellwig @ 2007-02-08 19:38 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Sumant Patro, James.Bottomley, linux-scsi, linux-kernel,
	neela.kolli, bo.yang, sumant.patro

On Wed, Feb 07, 2007 at 01:30:20PM -0800, Andrew Morton wrote:
> On Tue, 06 Feb 2007 14:19:54 -0800
> Sumant Patro <sumantp@lsil.com> 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.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing
  2007-02-07 22:02   ` James Bottomley
@ 2008-10-16  0:17     ` CaT
  2008-10-16 13:54         ` Yang, Bo
  0 siblings, 1 reply; 8+ messages in thread
From: CaT @ 2008-10-16  0:17 UTC (permalink / raw)
  To: James Bottomley
  Cc: Andrew Morton, Sumant Patro, linux-scsi, linux-kernel,
	neela.kolli, bo.yang, sumant.patro

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing
  2008-10-16  0:17     ` CaT
@ 2008-10-16 13:54         ` Yang, Bo
  0 siblings, 0 replies; 8+ messages in thread
From: Yang, Bo @ 2008-10-16 13:54 UTC (permalink / raw)
  To: CaT, James Bottomley
  Cc: Andrew Morton, Patro, Sumant, linux-scsi, linux-kernel, Kolli,
	Neela, Patro, Sumant

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

Thanks,

Bo Yang

-----Original Message-----
From: CaT [mailto:cat@zip.com.au]
Sent: Wednesday, October 15, 2008 8:17 PM
To: James Bottomley
Cc: Andrew Morton; Patro, Sumant; linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org; 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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing
@ 2008-10-16 13:54         ` Yang, Bo
  0 siblings, 0 replies; 8+ messages in thread
From: Yang, Bo @ 2008-10-16 13:54 UTC (permalink / raw)
  To: CaT, James Bottomley
  Cc: Andrew Morton, Patro, Sumant, linux-scsi, linux-kernel, Kolli, Neela

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

Thanks,

Bo Yang

-----Original Message-----
From: CaT [mailto:cat@zip.com.au]
Sent: Wednesday, October 15, 2008 8:17 PM
To: James Bottomley
Cc: Andrew Morton; Patro, Sumant; linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org; 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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing
  2008-10-16 13:54         ` Yang, Bo
  (?)
@ 2008-10-16 21:51         ` CaT
  -1 siblings, 0 replies; 8+ messages in thread
From: CaT @ 2008-10-16 21:51 UTC (permalink / raw)
  To: Yang, Bo
  Cc: James Bottomley, Andrew Morton, Patro, Sumant, linux-scsi,
	linux-kernel, Kolli, Neela

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-10-16 22:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-06 22:19 [PATCH 4/5] scsi: megaraid_sas - preallocate memory for ioctl processing Sumant Patro
2007-02-07 21:30 ` Andrew Morton
2007-02-07 22:02   ` James Bottomley
2008-10-16  0:17     ` CaT
2008-10-16 13:54       ` Yang, Bo
2008-10-16 13:54         ` Yang, Bo
2008-10-16 21:51         ` CaT
2007-02-08 19:38   ` Christoph Hellwig

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.