[svn-commits] sruffell: branch linux/2.5 r10146 - /linux/branches/2.5/drivers/dahdi/wctdm24...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Aug 18 14:35:05 CDT 2011


Author: sruffell
Date: Thu Aug 18 14:35:01 2011
New Revision: 10146

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=10146
Log:
wctdm24xxp: Use our own free list for IRQ commands.

Really only *necessary* when SLAB debugging is enabled, but in that
case, can reduce the chance of latency bumps when first loading the
driver. Otherwise the constant slab poisoning / checking in interrupt
context from the kmalloc / kfrees is too much.

Signed-off-by: Shaun Ruffell <sruffell at digium.com>
Acked-by: Russ Meyerriecks <rmeyerriecks at digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10144

Modified:
    linux/branches/2.5/drivers/dahdi/wctdm24xxp/base.c
    linux/branches/2.5/drivers/dahdi/wctdm24xxp/wctdm24xxp.h

Modified: linux/branches/2.5/drivers/dahdi/wctdm24xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/branches/2.5/drivers/dahdi/wctdm24xxp/base.c?view=diff&rev=10146&r1=10145&r2=10146
==============================================================================
--- linux/branches/2.5/drivers/dahdi/wctdm24xxp/base.c (original)
+++ linux/branches/2.5/drivers/dahdi/wctdm24xxp/base.c Thu Aug 18 14:35:01 2011
@@ -867,6 +867,8 @@
 		return;
 	}
 
+	list_add(&cmd->node, &wc->free_isr_commands);
+
 	switch (mod->type) {
 	case FXS:
 		mod->isrshadow[(68 == address) ? 0 : 1] = value;
@@ -884,8 +886,6 @@
 	default:
 		break;
 	}
-
-	kfree(cmd);
 }
 
 /* Call with wc.reglock held and local interrupts disabled. */
@@ -894,9 +894,15 @@
 {
 	struct wctdm_cmd *cmd;
 
-	cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
-	if (unlikely(!cmd))
-		return;
+	if (!list_empty(&wc->free_isr_commands)) {
+		cmd = list_entry(wc->free_isr_commands.next,
+				 struct wctdm_cmd, node);
+		list_del(&cmd->node);
+	} else {
+		cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
+		if (unlikely(!cmd))
+			return;
+	}
 
 	cmd->cmd = CMD_RD(address);
 	cmd->complete = NULL;
@@ -4633,6 +4639,7 @@
 		list_splice_init(&mod->pending_cmds, &local_list);
 		list_splice_init(&mod->active_cmds, &local_list);
 	}
+	list_splice_init(&wc->free_isr_commands, &local_list);
 	spin_unlock_irqrestore(&wc->reglock, flags);
 
 	while (!list_empty(&local_list)) {
@@ -5219,6 +5226,39 @@
 		if (NONE == wc->mods[i].type)
 			wc->tdm410leds |= (1 << i);
 	}
+}
+
+/**
+ * wctdm_allocate_irq_commands - Preallocate some commands for use in interrupt context.
+ * @wc:	The board which we're allocating for.
+ * @count:	The number of IRQ commands to allocate.
+ *
+ * We need a minimum of 4 * the current latency worth of commands for each
+ * analog module. When the latency grows, new commands will be allocated, but
+ * this just represents are best guess as to the number of commands we'll need
+ * after probing for modules, and reduces the chance that we'll allocate
+ * memory in interrupt context when the driver first loads.
+ *
+ */
+static void wctdm_allocate_irq_commands(struct wctdm *wc, unsigned int count)
+{
+	unsigned long flags;
+	LIST_HEAD(local_list);
+
+	if (!count)
+		return;
+
+	while (count--) {
+		struct wctdm_cmd *cmd;
+		cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+		if (!cmd)
+			break;
+		list_add(&cmd->node, &local_list);
+	}
+
+	spin_lock_irqsave(&wc->reglock, flags);
+	list_splice(&local_list, &wc->free_isr_commands);
+	spin_unlock_irqrestore(&wc->reglock, flags);
 }
 
 #ifdef USE_ASYNC_INIT
@@ -5266,6 +5306,7 @@
 	spin_lock_init(&wc->frame_list_lock);
 	init_waitqueue_head(&wc->regq);
 	spin_lock_init(&wc->reglock);
+	INIT_LIST_HEAD(&wc->free_isr_commands);
 	wc->oldsync = -1;
 
 	wc->board_name = kasprintf(GFP_KERNEL, "%s%d", wctdm_driver.name, pos);
@@ -5492,6 +5533,7 @@
 		}
 	}
 
+	wctdm_allocate_irq_commands(wc, anamods * latency * 4);
 	wc->not_ready--;
 
 	dev_info(&wc->vb.pdev->dev,

Modified: linux/branches/2.5/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
URL: http://svnview.digium.com/svn/dahdi/linux/branches/2.5/drivers/dahdi/wctdm24xxp/wctdm24xxp.h?view=diff&rev=10146&r1=10145&r2=10146
==============================================================================
--- linux/branches/2.5/drivers/dahdi/wctdm24xxp/wctdm24xxp.h (original)
+++ linux/branches/2.5/drivers/dahdi/wctdm24xxp/wctdm24xxp.h Thu Aug 18 14:35:01 2011
@@ -255,6 +255,7 @@
 
 	spinlock_t reglock;			/* held when accessing anything affecting the module array */
 	wait_queue_head_t regq;
+	struct list_head free_isr_commands;
 
 	struct wctdm_module mods[NUM_MODULES];
 




More information about the svn-commits mailing list