kfifo: move struct kfifo in place
This is a new generic kernel FIFO implementation. The current kernel fifo API is not very widely used, because it has to many constrains. Only 17 files in the current 2.6.31-rc5 used it. FIFO's are like list's a very basic thing and a kfifo API which handles the most use case would save a lot of development time and memory resources. I think this are the reasons why kfifo is not in use: - The API is to simple, important functions are missing - A fifo can be only allocated dynamically - There is a requirement of a spinlock whether you need it or not - There is no support for data records inside a fifo So I decided to extend the kfifo in a more generic way without blowing up the API to much. The new API has the following benefits: - Generic usage: For kernel internal use and/or device driver. - Provide an API for the most use case. - Slim API: The whole API provides 25 functions. - Linux style habit. - DECLARE_KFIFO, DEFINE_KFIFO and INIT_KFIFO Macros - Direct copy_to_user from the fifo and copy_from_user into the fifo. - The kfifo itself is an in place member of the using data structure, this save an indirection access and does not waste the kernel allocator. - Lockless access: if only one reader and one writer is active on the fifo, which is the common use case, no additional locking is necessary. - Remove spinlock - give the user the freedom of choice what kind of locking to use if one is required. - Ability to handle records. Three type of records are supported: - Variable length records between 0-255 bytes, with a record size field of 1 bytes. - Variable length records between 0-65535 bytes, with a record size field of 2 bytes. - Fixed size records, which no record size field. - Preserve memory resource. - Performance! - Easy to use! This patch: Since most users want to have the kfifo as part of another object, reorganize the code to allow including struct kfifo in another data structure. This requires changing the kfifo_alloc and kfifo_init prototypes so that we pass an existing kfifo pointer into them. This patch changes the implementation and all existing users. [akpm@linux-foundation.org: fix warning] Signed-off-by: Stefani Seibold <stefani@seibold.net> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com> Acked-by: Andi Kleen <ak@linux.intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Цей коміт міститься в:

зафіксовано
Linus Torvalds

джерело
2ec91eec47
коміт
4546548789
@@ -39,12 +39,12 @@
|
||||
#include "cxio_resource.h"
|
||||
#include "cxio_hal.h"
|
||||
|
||||
static struct kfifo *rhdl_fifo;
|
||||
static struct kfifo rhdl_fifo;
|
||||
static spinlock_t rhdl_fifo_lock;
|
||||
|
||||
#define RANDOM_SIZE 16
|
||||
|
||||
static int __cxio_init_resource_fifo(struct kfifo **fifo,
|
||||
static int __cxio_init_resource_fifo(struct kfifo *fifo,
|
||||
spinlock_t *fifo_lock,
|
||||
u32 nr, u32 skip_low,
|
||||
u32 skip_high,
|
||||
@@ -55,12 +55,11 @@ static int __cxio_init_resource_fifo(struct kfifo **fifo,
|
||||
u32 rarray[16];
|
||||
spin_lock_init(fifo_lock);
|
||||
|
||||
*fifo = kfifo_alloc(nr * sizeof(u32), GFP_KERNEL, fifo_lock);
|
||||
if (IS_ERR(*fifo))
|
||||
if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL, fifo_lock))
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < skip_low + skip_high; i++)
|
||||
__kfifo_put(*fifo, (unsigned char *) &entry, sizeof(u32));
|
||||
__kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32));
|
||||
if (random) {
|
||||
j = 0;
|
||||
random_bytes = random32();
|
||||
@@ -72,33 +71,33 @@ static int __cxio_init_resource_fifo(struct kfifo **fifo,
|
||||
random_bytes = random32();
|
||||
}
|
||||
idx = (random_bytes >> (j * 2)) & 0xF;
|
||||
__kfifo_put(*fifo,
|
||||
__kfifo_put(fifo,
|
||||
(unsigned char *) &rarray[idx],
|
||||
sizeof(u32));
|
||||
rarray[idx] = i;
|
||||
j++;
|
||||
}
|
||||
for (i = 0; i < RANDOM_SIZE; i++)
|
||||
__kfifo_put(*fifo,
|
||||
__kfifo_put(fifo,
|
||||
(unsigned char *) &rarray[i],
|
||||
sizeof(u32));
|
||||
} else
|
||||
for (i = skip_low; i < nr - skip_high; i++)
|
||||
__kfifo_put(*fifo, (unsigned char *) &i, sizeof(u32));
|
||||
__kfifo_put(fifo, (unsigned char *) &i, sizeof(u32));
|
||||
|
||||
for (i = 0; i < skip_low + skip_high; i++)
|
||||
kfifo_get(*fifo, (unsigned char *) &entry, sizeof(u32));
|
||||
kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxio_init_resource_fifo(struct kfifo **fifo, spinlock_t * fifo_lock,
|
||||
static int cxio_init_resource_fifo(struct kfifo *fifo, spinlock_t * fifo_lock,
|
||||
u32 nr, u32 skip_low, u32 skip_high)
|
||||
{
|
||||
return (__cxio_init_resource_fifo(fifo, fifo_lock, nr, skip_low,
|
||||
skip_high, 0));
|
||||
}
|
||||
|
||||
static int cxio_init_resource_fifo_random(struct kfifo **fifo,
|
||||
static int cxio_init_resource_fifo_random(struct kfifo *fifo,
|
||||
spinlock_t * fifo_lock,
|
||||
u32 nr, u32 skip_low, u32 skip_high)
|
||||
{
|
||||
@@ -113,15 +112,14 @@ static int cxio_init_qpid_fifo(struct cxio_rdev *rdev_p)
|
||||
|
||||
spin_lock_init(&rdev_p->rscp->qpid_fifo_lock);
|
||||
|
||||
rdev_p->rscp->qpid_fifo = kfifo_alloc(T3_MAX_NUM_QP * sizeof(u32),
|
||||
if (kfifo_alloc(&rdev_p->rscp->qpid_fifo, T3_MAX_NUM_QP * sizeof(u32),
|
||||
GFP_KERNEL,
|
||||
&rdev_p->rscp->qpid_fifo_lock);
|
||||
if (IS_ERR(rdev_p->rscp->qpid_fifo))
|
||||
&rdev_p->rscp->qpid_fifo_lock))
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 16; i < T3_MAX_NUM_QP; i++)
|
||||
if (!(i & rdev_p->qpmask))
|
||||
__kfifo_put(rdev_p->rscp->qpid_fifo,
|
||||
__kfifo_put(&rdev_p->rscp->qpid_fifo,
|
||||
(unsigned char *) &i, sizeof(u32));
|
||||
return 0;
|
||||
}
|
||||
@@ -134,7 +132,7 @@ int cxio_hal_init_rhdl_resource(u32 nr_rhdl)
|
||||
|
||||
void cxio_hal_destroy_rhdl_resource(void)
|
||||
{
|
||||
kfifo_free(rhdl_fifo);
|
||||
kfifo_free(&rhdl_fifo);
|
||||
}
|
||||
|
||||
/* nr_* must be power of 2 */
|
||||
@@ -167,11 +165,11 @@ int cxio_hal_init_resource(struct cxio_rdev *rdev_p,
|
||||
goto pdid_err;
|
||||
return 0;
|
||||
pdid_err:
|
||||
kfifo_free(rscp->cqid_fifo);
|
||||
kfifo_free(&rscp->cqid_fifo);
|
||||
cqid_err:
|
||||
kfifo_free(rscp->qpid_fifo);
|
||||
kfifo_free(&rscp->qpid_fifo);
|
||||
qpid_err:
|
||||
kfifo_free(rscp->tpt_fifo);
|
||||
kfifo_free(&rscp->tpt_fifo);
|
||||
tpt_err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -195,17 +193,17 @@ static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry)
|
||||
|
||||
u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp)
|
||||
{
|
||||
return cxio_hal_get_resource(rscp->tpt_fifo);
|
||||
return cxio_hal_get_resource(&rscp->tpt_fifo);
|
||||
}
|
||||
|
||||
void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag)
|
||||
{
|
||||
cxio_hal_put_resource(rscp->tpt_fifo, stag);
|
||||
cxio_hal_put_resource(&rscp->tpt_fifo, stag);
|
||||
}
|
||||
|
||||
u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp)
|
||||
{
|
||||
u32 qpid = cxio_hal_get_resource(rscp->qpid_fifo);
|
||||
u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo);
|
||||
PDBG("%s qpid 0x%x\n", __func__, qpid);
|
||||
return qpid;
|
||||
}
|
||||
@@ -213,35 +211,35 @@ u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp)
|
||||
void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid)
|
||||
{
|
||||
PDBG("%s qpid 0x%x\n", __func__, qpid);
|
||||
cxio_hal_put_resource(rscp->qpid_fifo, qpid);
|
||||
cxio_hal_put_resource(&rscp->qpid_fifo, qpid);
|
||||
}
|
||||
|
||||
u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp)
|
||||
{
|
||||
return cxio_hal_get_resource(rscp->cqid_fifo);
|
||||
return cxio_hal_get_resource(&rscp->cqid_fifo);
|
||||
}
|
||||
|
||||
void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid)
|
||||
{
|
||||
cxio_hal_put_resource(rscp->cqid_fifo, cqid);
|
||||
cxio_hal_put_resource(&rscp->cqid_fifo, cqid);
|
||||
}
|
||||
|
||||
u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp)
|
||||
{
|
||||
return cxio_hal_get_resource(rscp->pdid_fifo);
|
||||
return cxio_hal_get_resource(&rscp->pdid_fifo);
|
||||
}
|
||||
|
||||
void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid)
|
||||
{
|
||||
cxio_hal_put_resource(rscp->pdid_fifo, pdid);
|
||||
cxio_hal_put_resource(&rscp->pdid_fifo, pdid);
|
||||
}
|
||||
|
||||
void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp)
|
||||
{
|
||||
kfifo_free(rscp->tpt_fifo);
|
||||
kfifo_free(rscp->cqid_fifo);
|
||||
kfifo_free(rscp->qpid_fifo);
|
||||
kfifo_free(rscp->pdid_fifo);
|
||||
kfifo_free(&rscp->tpt_fifo);
|
||||
kfifo_free(&rscp->cqid_fifo);
|
||||
kfifo_free(&rscp->qpid_fifo);
|
||||
kfifo_free(&rscp->pdid_fifo);
|
||||
kfree(rscp);
|
||||
}
|
||||
|
||||
|
Посилання в новій задачі
Заблокувати користувача