[dahdi-commits] sruffell: linux/trunk r6245 - /linux/trunk/drivers/dahdi/wctc4xxp/base.c
SVN commits to the DAHDI project
dahdi-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 dahdi-commits
mailing list