mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
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.
[[email protected]: fix warning]
Signed-off-by: Stefani Seibold <[email protected]>
Acked-by: Greg Kroah-Hartman <[email protected]>
Acked-by: Mauro Carvalho Chehab <[email protected]>
Acked-by: Andi Kleen <[email protected]>
Acked-by: Arnd Bergmann <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
2ec91eec47
commit
4546548789
24 changed files with 238 additions and 259 deletions
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/kfifo.h>
|
||||
|
||||
#include "t3_cpl.h"
|
||||
#include "t3cdev.h"
|
||||
|
|
@ -75,13 +76,13 @@ struct cxio_hal_ctrl_qp {
|
|||
};
|
||||
|
||||
struct cxio_hal_resource {
|
||||
struct kfifo *tpt_fifo;
|
||||
struct kfifo tpt_fifo;
|
||||
spinlock_t tpt_fifo_lock;
|
||||
struct kfifo *qpid_fifo;
|
||||
struct kfifo qpid_fifo;
|
||||
spinlock_t qpid_fifo_lock;
|
||||
struct kfifo *cqid_fifo;
|
||||
struct kfifo cqid_fifo;
|
||||
spinlock_t cqid_fifo_lock;
|
||||
struct kfifo *pdid_fifo;
|
||||
struct kfifo pdid_fifo;
|
||||
spinlock_t pdid_fifo_lock;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue