Skip to content

Commit

Permalink
kfifo API type safety
Browse files Browse the repository at this point in the history
This patch enhances the type safety for the kfifo API.  It is now safe
to put const data into a non const FIFO and the API will now generate a
compiler warning when reading from the fifo where the destination
address is pointing to a const variable.

As a side effect the kfifo_put() does now expect the value of an element
instead a pointer to the element.  This was suggested Russell King.  It
make the handling of the kfifo_put easier since there is no need to
create a helper variable for getting the address of a pointer or to pass
integers of different sizes.

IMHO the API break is okay, since there are currently only six users of
kfifo_put().

The code is also cleaner by kicking out the "if (0)" expressions.

[[email protected]: coding-style fixes]
Signed-off-by: Stefani Seibold <[email protected]>
Cc: Russell King <[email protected]>
Cc: Hauke Mehrtens <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
sstefani authored and torvalds committed Nov 15, 2013
1 parent a019e48 commit 498d319
Show file tree
Hide file tree
Showing 10 changed files with 25 additions and 44 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/drm_flip_work.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
*/
void drm_flip_work_queue(struct drm_flip_work *work, void *val)
{
if (kfifo_put(&work->fifo, (const void **)&val)) {
if (kfifo_put(&work->fifo, val)) {
atomic_inc(&work->pending);
} else {
DRM_ERROR("%s fifo full!\n", work->name);
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/industrialio-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
ev.id = ev_code;
ev.timestamp = timestamp;

copied = kfifo_put(&ev_int->det_events, &ev);
copied = kfifo_put(&ev_int->det_events, ev);
if (copied != 0)
wake_up_locked_poll(&ev_int->wait, POLLIN);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/rt2x00/rt2800mmio.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
break;

if (!kfifo_put(&rt2x00dev->txstatus_fifo, &status)) {
if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) {
rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n");
break;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/rt2x00/rt2800usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,

valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID);
if (valid) {
if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status))
if (!kfifo_put(&rt2x00dev->txstatus_fifo, tx_status))
rt2x00_warn(rt2x00dev, "TX status FIFO overrun\n");

queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
Expand Down
2 changes: 1 addition & 1 deletion drivers/pci/pcie/aer/aerdrv_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
};

spin_lock_irqsave(&aer_recover_ring_lock, flags);
if (kfifo_put(&aer_recover_ring, &entry))
if (kfifo_put(&aer_recover_ring, entry))
schedule_work(&aer_recover_work);
else
pr_err("AER recover: Buffer overflow when recovering AER for %04x:%02x:%02x:%x\n",
Expand Down
47 changes: 14 additions & 33 deletions include/linux/kfifo.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* A generic kernel FIFO implementation
*
* Copyright (C) 2009/2010 Stefani Seibold <[email protected]>
* Copyright (C) 2013 Stefani Seibold <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -67,9 +67,10 @@ struct __kfifo {
union { \
struct __kfifo kfifo; \
datatype *type; \
const datatype *const_type; \
char (*rectype)[recsize]; \
ptrtype *ptr; \
const ptrtype *ptr_const; \
ptrtype const *ptr_const; \
}

#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \
Expand Down Expand Up @@ -386,16 +387,12 @@ __kfifo_int_must_check_helper( \
#define kfifo_put(fifo, val) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((val) + 1) __val = (val); \
typeof(*__tmp->const_type) __val = (val); \
unsigned int __ret; \
const size_t __recsize = sizeof(*__tmp->rectype); \
size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) { \
typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \
__dummy = (typeof(__val))NULL; \
} \
if (__recsize) \
__ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \
__ret = __kfifo_in_r(__kfifo, &__val, sizeof(__val), \
__recsize); \
else { \
__ret = !kfifo_is_full(__tmp); \
Expand All @@ -404,7 +401,7 @@ __kfifo_int_must_check_helper( \
((typeof(__tmp->type))__kfifo->data) : \
(__tmp->buf) \
)[__kfifo->in & __tmp->kfifo.mask] = \
*(typeof(__tmp->type))__val; \
(typeof(*__tmp->type))__val; \
smp_wmb(); \
__kfifo->in++; \
} \
Expand All @@ -415,7 +412,7 @@ __kfifo_int_must_check_helper( \
/**
* kfifo_get - get data from the fifo
* @fifo: address of the fifo to be used
* @val: the var where to store the data to be added
* @val: address where to store the data
*
* This macro reads the data from the fifo.
* It returns 0 if the fifo was empty. Otherwise it returns the number
Expand All @@ -428,12 +425,10 @@ __kfifo_int_must_check_helper( \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((val) + 1) __val = (val); \
typeof(__tmp->ptr) __val = (val); \
unsigned int __ret; \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) \
__val = (typeof(__tmp->ptr))0; \
if (__recsize) \
__ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \
__recsize); \
Expand All @@ -456,7 +451,7 @@ __kfifo_uint_must_check_helper( \
/**
* kfifo_peek - get data from the fifo without removing
* @fifo: address of the fifo to be used
* @val: the var where to store the data to be added
* @val: address where to store the data
*
* This reads the data from the fifo without removing it from the fifo.
* It returns 0 if the fifo was empty. Otherwise it returns the number
Expand All @@ -469,12 +464,10 @@ __kfifo_uint_must_check_helper( \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((val) + 1) __val = (val); \
typeof(__tmp->ptr) __val = (val); \
unsigned int __ret; \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) \
__val = (typeof(__tmp->ptr))NULL; \
if (__recsize) \
__ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \
__recsize); \
Expand Down Expand Up @@ -508,14 +501,10 @@ __kfifo_uint_must_check_helper( \
#define kfifo_in(fifo, buf, n) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((buf) + 1) __buf = (buf); \
typeof(__tmp->ptr_const) __buf = (buf); \
unsigned long __n = (n); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) { \
typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \
__dummy = (typeof(__buf))NULL; \
} \
(__recsize) ?\
__kfifo_in_r(__kfifo, __buf, __n, __recsize) : \
__kfifo_in(__kfifo, __buf, __n); \
Expand Down Expand Up @@ -561,14 +550,10 @@ __kfifo_uint_must_check_helper( \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((buf) + 1) __buf = (buf); \
typeof(__tmp->ptr) __buf = (buf); \
unsigned long __n = (n); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) { \
typeof(__tmp->ptr) __dummy = NULL; \
__buf = __dummy; \
} \
(__recsize) ?\
__kfifo_out_r(__kfifo, __buf, __n, __recsize) : \
__kfifo_out(__kfifo, __buf, __n); \
Expand Down Expand Up @@ -773,14 +758,10 @@ __kfifo_uint_must_check_helper( \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof((buf) + 1) __buf = (buf); \
typeof(__tmp->ptr) __buf = (buf); \
unsigned long __n = (n); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (0) { \
typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \
__buf = __dummy; \
} \
(__recsize) ? \
__kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \
__kfifo_out_peek(__kfifo, __buf, __n); \
Expand Down
2 changes: 1 addition & 1 deletion mm/memory-failure.c
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@ void memory_failure_queue(unsigned long pfn, int trapno, int flags)

mf_cpu = &get_cpu_var(memory_failure_cpu);
spin_lock_irqsave(&mf_cpu->lock, proc_flags);
if (kfifo_put(&mf_cpu->fifo, &entry))
if (kfifo_put(&mf_cpu->fifo, entry))
schedule_work_on(smp_processor_id(), &mf_cpu->work);
else
pr_err("Memory failure: buffer overflow when queuing memory failure at %#lx\n",
Expand Down
4 changes: 2 additions & 2 deletions samples/kfifo/bytestream-example.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static int __init testfunc(void)

/* put values into the fifo */
for (i = 0; i != 10; i++)
kfifo_put(&test, &i);
kfifo_put(&test, i);

/* show the number of used elements */
printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test));
Expand All @@ -85,7 +85,7 @@ static int __init testfunc(void)
kfifo_skip(&test);

/* put values into the fifo until is full */
for (i = 20; kfifo_put(&test, &i); i++)
for (i = 20; kfifo_put(&test, i); i++)
;

printk(KERN_INFO "queue len: %u\n", kfifo_len(&test));
Expand Down
2 changes: 1 addition & 1 deletion samples/kfifo/dma-example.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static int __init example_init(void)
kfifo_in(&fifo, "test", 4);

for (i = 0; i != 9; i++)
kfifo_put(&fifo, &i);
kfifo_put(&fifo, i);

/* kick away first byte */
kfifo_skip(&fifo);
Expand Down
4 changes: 2 additions & 2 deletions samples/kfifo/inttype-example.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static int __init testfunc(void)

/* put values into the fifo */
for (i = 0; i != 10; i++)
kfifo_put(&test, &i);
kfifo_put(&test, i);

/* show the number of used elements */
printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test));
Expand All @@ -78,7 +78,7 @@ static int __init testfunc(void)
kfifo_skip(&test);

/* put values into the fifo until is full */
for (i = 20; kfifo_put(&test, &i); i++)
for (i = 20; kfifo_put(&test, i); i++)
;

printk(KERN_INFO "queue len: %u\n", kfifo_len(&test));
Expand Down

0 comments on commit 498d319

Please sign in to comment.