Commit 2b8b61aa authored by Christoph Jaeger's avatar Christoph Jaeger Committed by Greg Kroah-Hartman
Browse files

staging: ozwpan: Use slab cache for oz_elt_info allocation



Use a slab cache rather than rolling our own free list.

Signed-off-by: default avatarChristoph Jaeger <email@christophjaeger.info>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9e6fbdde
Loading
Loading
Loading
Loading
+3 −65
Original line number Diff line number Diff line
@@ -10,9 +10,6 @@
#include "ozeltbuf.h"
#include "ozpd.h"

#define OZ_ELT_INFO_MAGIC_USED	0x35791057
#define OZ_ELT_INFO_MAGIC_FREE	0x78940102

/*
 * Context: softirq-serialized
 */
@@ -22,7 +19,6 @@ void oz_elt_buf_init(struct oz_elt_buf *buf)
	INIT_LIST_HEAD(&buf->stream_list);
	INIT_LIST_HEAD(&buf->order_list);
	INIT_LIST_HEAD(&buf->isoc_list);
	buf->max_free_elts = 32;
	spin_lock_init(&buf->lock);
}

@@ -49,14 +45,6 @@ void oz_elt_buf_term(struct oz_elt_buf *buf)
			kfree(ei);
		}
	}
	/* Free any elelment in the pool. */
	while (buf->elt_pool) {
		struct oz_elt_info *ei =
			container_of(buf->elt_pool, struct oz_elt_info, link);
		buf->elt_pool = buf->elt_pool->next;
		kfree(ei);
	}
	buf->free_elts = 0;
}

/*
@@ -66,27 +54,8 @@ struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf)
{
	struct oz_elt_info *ei;

	spin_lock_bh(&buf->lock);
	if (buf->free_elts && buf->elt_pool) {
		ei = container_of(buf->elt_pool, struct oz_elt_info, link);
		buf->elt_pool = ei->link.next;
		buf->free_elts--;
		spin_unlock_bh(&buf->lock);
		if (ei->magic != OZ_ELT_INFO_MAGIC_FREE) {
			oz_dbg(ON, "%s: ei with bad magic: 0x%x\n",
			       __func__, ei->magic);
		}
	} else {
		spin_unlock_bh(&buf->lock);
		ei = kmalloc(sizeof(struct oz_elt_info), GFP_ATOMIC);
	}
	ei = kmem_cache_zalloc(oz_elt_info_cache, GFP_ATOMIC);
	if (ei) {
		ei->flags = 0;
		ei->app_id = 0;
		ei->callback = NULL;
		ei->context = 0;
		ei->stream = NULL;
		ei->magic = OZ_ELT_INFO_MAGIC_USED;
		INIT_LIST_HEAD(&ei->link);
		INIT_LIST_HEAD(&ei->link_order);
	}
@@ -99,17 +68,8 @@ struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf)
 */
void oz_elt_info_free(struct oz_elt_buf *buf, struct oz_elt_info *ei)
{
	if (ei) {
		if (ei->magic == OZ_ELT_INFO_MAGIC_USED) {
			buf->free_elts++;
			ei->link.next = buf->elt_pool;
			buf->elt_pool = &ei->link;
			ei->magic = OZ_ELT_INFO_MAGIC_FREE;
		} else {
			oz_dbg(ON, "%s: bad magic ei: %p magic: 0x%x\n",
			       __func__, ei, ei->magic);
		}
	}
	if (ei)
		kmem_cache_free(oz_elt_info_cache, ei);
}

/*------------------------------------------------------------------------------
@@ -313,25 +273,3 @@ int oz_are_elts_available(struct oz_elt_buf *buf)
{
	return buf->order_list.next != &buf->order_list;
}

void oz_trim_elt_pool(struct oz_elt_buf *buf)
{
	struct list_head *free = NULL;
	struct list_head *e;

	spin_lock_bh(&buf->lock);
	while (buf->free_elts > buf->max_free_elts) {
		e = buf->elt_pool;
		buf->elt_pool = e->next;
		e->next = free;
		free = e;
		buf->free_elts--;
	}
	spin_unlock_bh(&buf->lock);
	while (free) {
		struct oz_elt_info *ei =
			container_of(free, struct oz_elt_info, link);
		free = free->next;
		kfree(ei);
	}
}
+0 −5
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ struct oz_elt_info {
	struct oz_elt_stream *stream;
	u8 data[sizeof(struct oz_elt) + OZ_MAX_ELT_PAYLOAD];
	int length;
	unsigned magic;
};
/* Flags values */
#define OZ_EI_F_MARKED		0x1
@@ -44,9 +43,6 @@ struct oz_elt_buf {
	struct list_head stream_list;
	struct list_head order_list;
	struct list_head isoc_list;
	struct list_head *elt_pool;
	int free_elts;
	int max_free_elts;
	u8 tx_seq_num[OZ_NB_APPS];
};

@@ -64,7 +60,6 @@ int oz_queue_elt_info(struct oz_elt_buf *buf, u8 isoc, u8 id,
int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len,
		unsigned max_len, struct list_head *list);
int oz_are_elts_available(struct oz_elt_buf *buf);
void oz_trim_elt_pool(struct oz_elt_buf *buf);

#endif /* _OZELTBUF_H */
+0 −2
Original line number Diff line number Diff line
@@ -504,8 +504,6 @@ static void oz_retire_frame(struct oz_pd *pd, struct oz_tx_frame *f)
		spin_unlock_bh(&pd->elt_buff.lock);
	}
	oz_tx_frame_free(pd, f);
	if (pd->elt_buff.free_elts > pd->elt_buff.max_free_elts)
		oz_trim_elt_pool(&pd->elt_buff);
}

/*
+2 −0
Original line number Diff line number Diff line
@@ -130,4 +130,6 @@ void oz_handle_app_elt(struct oz_pd *pd, u8 app_id, struct oz_elt *elt);
void oz_apps_init(void);
void oz_apps_term(void);

extern struct kmem_cache *oz_elt_info_cache;

#endif /* Sentry */
+9 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/etherdevice.h>
#include <linux/errno.h>
#include <linux/ieee80211.h>
#include <linux/slab.h>
#include "ozdbg.h"
#include "ozprotocol.h"
#include "ozeltbuf.h"
@@ -51,6 +52,8 @@ static u8 g_session_id;
static u16 g_apps = 0x1;
static int g_processing_rx;

struct kmem_cache *oz_elt_info_cache;

/*
 * Context: softirq-serialized
 */
@@ -479,6 +482,8 @@ void oz_protocol_term(void)
	}
	spin_unlock_bh(&g_polling_lock);
	oz_dbg(ON, "Protocol stopped\n");

	kmem_cache_destroy(oz_elt_info_cache);
}

/*
@@ -762,6 +767,10 @@ static char *oz_get_next_device_name(char *s, char *dname, int max_size)
 */
int oz_protocol_init(char *devs)
{
	oz_elt_info_cache = KMEM_CACHE(oz_elt_info, 0);
	if (!oz_elt_info_cache)
		return -ENOMEM;

	skb_queue_head_init(&g_rx_queue);
	if (devs[0] == '*') {
		oz_binding_add(NULL);
Loading