[svn-commits] sruffell: linux/trunk r6245 - /linux/trunk/drivers/dahdi/wctc4xxp/base.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Mar 24 14:08:15 CDT 2009


Author: sruffell
Date: Tue Mar 24 14:08:12 2009
New Revision: 6245

URL: http://svn.digium.com/svn-view/dahdi?view=rev&rev=6245
Log:
Do not allocate more memory than is needed when sending packets.

Modified:
    linux/trunk/drivers/dahdi/wctc4xxp/base.c

Modified: linux/trunk/drivers/dahdi/wctc4xxp/base.c
URL: http://svn.digium.com/svn-view/dahdi/linux/trunk/drivers/dahdi/wctc4xxp/base.c?view=diff&rev=6245&r1=6244&r2=6245
==============================================================================
--- linux/trunk/drivers/dahdi/wctc4xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wctc4xxp/base.c Tue Mar 24 14:08:12 2009
@@ -192,12 +192,14 @@
 #define MAX_FRAME_SIZE 1518
 #define SFRAME_SIZE MAX_FRAME_SIZE
 
+#define DRING_SIZE (1 << 7) /* Must be a power of two */
+#define DRING_MASK (DRING_SIZE-1)
+#define MIN_PACKET_LEN  64
+
 #undef USE_CUSTOM_MEMCACHE
 
 /* Transcoder buffer (tcb) */
 struct tcb {
-	/* First field so that is aligned by default. */
-	u8 cmd[SFRAME_SIZE];
 	struct list_head node;
 	unsigned long timeout;
 	unsigned long retries;
@@ -224,11 +226,6 @@
 #endif
 };
 
-static inline void *hdr_from_cmd(struct tcb *cmd)
-{
-	return cmd->data;
-}
-
 static inline const struct csm_encaps_hdr *
 response_header(struct tcb *cmd)
 {
@@ -239,12 +236,9 @@
 static inline void
 initialize_cmd(struct tcb *cmd, unsigned long cmd_flags)
 {
-	memset(cmd, 0, sizeof(*cmd));
 	INIT_LIST_HEAD(&cmd->node);
 	init_completion(&cmd->complete);
 	cmd->flags = cmd_flags;
-	cmd->data = &cmd->cmd[0];
-	cmd->data_len = SFRAME_SIZE;
 	spin_lock_init(&cmd->lock);
 #ifdef USE_CUSTOM_MEMCACHE
 	cmd->sentinel = 0xdeadbeef;
@@ -327,30 +321,42 @@
 #endif /* USE_CUSTOM_MEMCACHE */
 
 static inline struct tcb *
-__alloc_cmd(gfp_t alloc_flags, unsigned long cmd_flags)
+__alloc_cmd(size_t size, gfp_t alloc_flags, unsigned long cmd_flags)
 {
 	struct tcb *cmd;
 
+	if (unlikely(size > SFRAME_SIZE))
+		return NULL;
+	if (size < MIN_PACKET_LEN)
+		size = MIN_PACKET_LEN;
 #ifdef USE_CUSTOM_MEMCACHE
 	cmd = my_cache_alloc(cmd_cache, alloc_flags);
 #else
 	cmd = kmem_cache_alloc(cmd_cache, alloc_flags);
 #endif
-	if (likely(cmd))
+	if (likely(cmd)) {
+		memset(cmd, 0, sizeof(*cmd));
+		cmd->data = kzalloc(size, alloc_flags);
+		if (unlikely(!cmd->data)) {
+			kmem_cache_free(cmd_cache, cmd);
+			return NULL;
+		}
+		cmd->data_len = size;
 		initialize_cmd(cmd, cmd_flags);
+	}
 	return cmd;
 }
 
 static struct tcb *
-alloc_cmd(void)
-{
-	return __alloc_cmd(GFP_KERNEL, 0);
+alloc_cmd(size_t size)
+{
+	return __alloc_cmd(size, GFP_KERNEL, 0);
 }
 
 static void
 __free_cmd(struct tcb *cmd)
 {
-	if (cmd->data != &cmd->cmd[0])
+	if (cmd)
 		kfree(cmd->data);
 #ifdef USE_CUSTOM_MEMCACHE
 	my_cache_free(cmd_cache, cmd);
@@ -541,7 +547,7 @@
 {
 	const gfp_t alloc_flags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
 	struct tcb *cmd;
-	cmd = __alloc_cmd(alloc_flags, 0);
+	cmd = __alloc_cmd(skb->len, alloc_flags, 0);
 	if (cmd) {
 		int res;
 		cmd->data_len = skb->len;
@@ -855,10 +861,6 @@
 	__le32 container; /* Unused */
 } __attribute__((packed));
 
-#define DRING_SIZE (1 << 7) /* Must be a power of two */
-#define DRING_MASK (DRING_SIZE-1)
-#define MIN_PACKET_LEN  64
-
 struct wctc4xxp_descriptor_ring {
 	/* Pointer to an array of descriptors to give to hardware. */
 	struct wctc4xxp_descriptor *desc;
@@ -1006,6 +1008,7 @@
 		--dr->count;
 		WARN_ON(!c);
 		c->data_len = (d->des0 >> 16) & BUFFER1_SIZE_MASK;
+		WARN_ON(c->data_len > SFRAME_SIZE);
 	} else {
 		c = NULL;
 	}
@@ -1111,7 +1114,7 @@
 
 static void
 create_supervisor_cmd(struct wcdte *wc, struct tcb *cmd, u8 type, u8 class,
-	u16 function, const u16 *parameters, int num_parameters)
+	u16 function, const u16 *parameters, const int num_parameters)
 {
 	struct csm_encaps_hdr *hdr = cmd->data;
 	int i;
@@ -1520,7 +1523,7 @@
 	struct rtp_packet *packet;
 	struct tcb *cmd;
 
-	cmd = alloc_cmd();
+	cmd = alloc_cmd(sizeof(*packet) + inbytes);
 	if (!cmd)
 		return NULL;
 
@@ -1567,8 +1570,7 @@
 	packet->rtphdr.timestamp =  cpu_to_be32(cpvt->timestamp);
 	packet->rtphdr.ssrc =	    cpu_to_be32(cpvt->ssrc);
 
-	cmd->data_len = sizeof(*packet) + inbytes;
-
+	WARN_ON(cmd->data_len > SFRAME_SIZE);
 	return cmd;
 }
 static void
@@ -2036,7 +2038,7 @@
 		spin_lock(&wc->rx_list_lock);
 		list_add_tail(&cmd->node, &wc->rx_list);
 		spin_unlock(&wc->rx_list_lock);
-		cmd = __alloc_cmd(GFP_ATOMIC, 0);
+		cmd = __alloc_cmd(SFRAME_SIZE, GFP_ATOMIC, 0);
 		if (!cmd) {
 			DTE_PRINTK(ERR, "Out of memory in %s.\n", __func__);
 		} else {
@@ -2224,7 +2226,7 @@
 {
 	struct tcb *cmd;
 	struct csm_encaps_hdr *hdr;
-	cmd = __alloc_cmd(ALLOC_FLAGS, 0);
+	cmd = __alloc_cmd(sizeof(*hdr), ALLOC_FLAGS, 0);
 	if (!cmd) {
 		WARN_ON(1);
 		return;
@@ -2237,7 +2239,6 @@
 	hdr->control = 0xe0;
 	hdr->channel = channel;
 
-	cmd->data_len = sizeof(*hdr);
 	wctc4xxp_transmit_cmd(wc, cmd);
 }
 
@@ -2701,12 +2702,12 @@
 	struct tcb *cmd;
 
 	for (i = 0; i < DRING_SIZE; ++i) {
-		cmd = alloc_cmd();
+		cmd = alloc_cmd(SFRAME_SIZE);
 		if (!cmd) {
 			WARN_ALWAYS();
 			return;
 		}
-		cmd->data_len = SFRAME_SIZE;
+		WARN_ON(SFRAME_SIZE != cmd->data_len);
 		res = wctc4xxp_submit(wc->rxd, cmd);
 		if (res) {
 			/* When we're starting the DMA, we should always be
@@ -2864,18 +2865,10 @@
 
 	byteloc = 17;
 
-	cmd = alloc_cmd();
+	cmd = alloc_cmd(SFRAME_SIZE);
 	if (!cmd)
 		return -ENOMEM;
 
-	if (MAX_FRAME_SIZE > cmd->data_len) {
-		cmd->data = kmalloc(MAX_FRAME_SIZE, GFP_KERNEL);
-		if (!(cmd->data)) {
-			free_cmd(cmd);
-			return -ENOMEM;
-		}
-		cmd->data_len = MAX_FRAME_SIZE;
-	}
 	while (byteloc < (firmware->size-20)) {
 		last_byteloc = byteloc;
 		length = (firmware->data[byteloc] << 8) |
@@ -2985,7 +2978,7 @@
 	u16 length;
 	struct tcb *cmd;
 
-	cmd = alloc_cmd();
+	cmd = alloc_cmd(SFRAME_SIZE);
 	if (!cmd)
 		return -ENOMEM;
 
@@ -3067,7 +3060,7 @@
 	int chan1, chan2, timeslot1, timeslot2;
 	struct tcb *cmd;
 
-	cmd = alloc_cmd();
+	cmd = alloc_cmd(SFRAME_SIZE);
 	if (!cmd)
 		return -ENOMEM;
 
@@ -3120,7 +3113,7 @@
 	struct tcb *cmd;
 	int tdm_bus;
 
-	cmd = alloc_cmd();
+	cmd = alloc_cmd(SFRAME_SIZE);
 	if (!cmd)
 		return -ENOMEM;
 




More information about the svn-commits mailing list