aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/industrialio-buffer.c
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2013-10-04 07:06:00 -0400
committerJonathan Cameron <jic23@kernel.org>2013-10-12 07:04:01 -0400
commit9e69c935fad9fd5f0550c51e3bd251cd30033136 (patch)
tree7900ed537ab31df1bc95e210fd99f187cd6efbc8 /drivers/iio/industrialio-buffer.c
parent2b6d598bc9043f51d2092d10392a6e3c161cdff7 (diff)
iio: Add reference counting for buffers
Since the buffer is accessed by userspace we can not just free the buffers memory once we are done with it in kernel space. There might still be open file descriptors and userspace still might be accessing the buffer. This patch adds support for reference counting to the IIO buffers. When a buffer is created and initialized its initial reference count is set to 1. Instead of freeing the memory of the buffer the buffer's _free() function will drop that reference again. But only after the last reference to the buffer has been dropped the buffer the buffer's memory will be freed. The IIO device will take a reference to its primary buffer. The patch adds a small helper function for this called iio_device_attach_buffer() which will get a reference to the buffer and assign the buffer to the IIO device. This function must be used instead of assigning the buffer to the device by hand. The reference is only dropped once the IIO device is freed and we can be sure that there are no more open file handles. A reference to a buffer will also be taken whenever the buffer is active to avoid the buffer being freed while data is still being send to it. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/industrialio-buffer.c')
-rw-r--r--drivers/iio/industrialio-buffer.c66
1 files changed, 61 insertions, 5 deletions
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index e9f389b9da69..36c39dcad850 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -74,6 +74,7 @@ void iio_buffer_init(struct iio_buffer *buffer)
74 INIT_LIST_HEAD(&buffer->demux_list); 74 INIT_LIST_HEAD(&buffer->demux_list);
75 INIT_LIST_HEAD(&buffer->buffer_list); 75 INIT_LIST_HEAD(&buffer->buffer_list);
76 init_waitqueue_head(&buffer->pollq); 76 init_waitqueue_head(&buffer->pollq);
77 kref_init(&buffer->ref);
77} 78}
78EXPORT_SYMBOL(iio_buffer_init); 79EXPORT_SYMBOL(iio_buffer_init);
79 80
@@ -454,6 +455,19 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev,
454 return bytes; 455 return bytes;
455} 456}
456 457
458static void iio_buffer_activate(struct iio_dev *indio_dev,
459 struct iio_buffer *buffer)
460{
461 iio_buffer_get(buffer);
462 list_add(&buffer->buffer_list, &indio_dev->buffer_list);
463}
464
465static void iio_buffer_deactivate(struct iio_buffer *buffer)
466{
467 list_del_init(&buffer->buffer_list);
468 iio_buffer_put(buffer);
469}
470
457void iio_disable_all_buffers(struct iio_dev *indio_dev) 471void iio_disable_all_buffers(struct iio_dev *indio_dev)
458{ 472{
459 struct iio_buffer *buffer, *_buffer; 473 struct iio_buffer *buffer, *_buffer;
@@ -466,7 +480,7 @@ void iio_disable_all_buffers(struct iio_dev *indio_dev)
466 480
467 list_for_each_entry_safe(buffer, _buffer, 481 list_for_each_entry_safe(buffer, _buffer,
468 &indio_dev->buffer_list, buffer_list) 482 &indio_dev->buffer_list, buffer_list)
469 list_del_init(&buffer->buffer_list); 483 iio_buffer_deactivate(buffer);
470 484
471 indio_dev->currentmode = INDIO_DIRECT_MODE; 485 indio_dev->currentmode = INDIO_DIRECT_MODE;
472 if (indio_dev->setup_ops->postdisable) 486 if (indio_dev->setup_ops->postdisable)
@@ -503,9 +517,9 @@ int iio_update_buffers(struct iio_dev *indio_dev,
503 indio_dev->active_scan_mask = NULL; 517 indio_dev->active_scan_mask = NULL;
504 518
505 if (remove_buffer) 519 if (remove_buffer)
506 list_del_init(&remove_buffer->buffer_list); 520 iio_buffer_deactivate(remove_buffer);
507 if (insert_buffer) 521 if (insert_buffer)
508 list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list); 522 iio_buffer_activate(indio_dev, insert_buffer);
509 523
510 /* If no buffers in list, we are done */ 524 /* If no buffers in list, we are done */
511 if (list_empty(&indio_dev->buffer_list)) { 525 if (list_empty(&indio_dev->buffer_list)) {
@@ -540,7 +554,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
540 * Roll back. 554 * Roll back.
541 * Note can only occur when adding a buffer. 555 * Note can only occur when adding a buffer.
542 */ 556 */
543 list_del_init(&insert_buffer->buffer_list); 557 iio_buffer_deactivate(insert_buffer);
544 if (old_mask) { 558 if (old_mask) {
545 indio_dev->active_scan_mask = old_mask; 559 indio_dev->active_scan_mask = old_mask;
546 success = -EINVAL; 560 success = -EINVAL;
@@ -631,7 +645,7 @@ error_run_postdisable:
631error_remove_inserted: 645error_remove_inserted:
632 646
633 if (insert_buffer) 647 if (insert_buffer)
634 list_del_init(&insert_buffer->buffer_list); 648 iio_buffer_deactivate(insert_buffer);
635 indio_dev->active_scan_mask = old_mask; 649 indio_dev->active_scan_mask = old_mask;
636 kfree(compound_mask); 650 kfree(compound_mask);
637error_ret: 651error_ret:
@@ -952,3 +966,45 @@ error_clear_mux_table:
952 return ret; 966 return ret;
953} 967}
954EXPORT_SYMBOL_GPL(iio_update_demux); 968EXPORT_SYMBOL_GPL(iio_update_demux);
969
970/**
971 * iio_buffer_release() - Free a buffer's resources
972 * @ref: Pointer to the kref embedded in the iio_buffer struct
973 *
974 * This function is called when the last reference to the buffer has been
975 * dropped. It will typically free all resources allocated by the buffer. Do not
976 * call this function manually, always use iio_buffer_put() when done using a
977 * buffer.
978 */
979static void iio_buffer_release(struct kref *ref)
980{
981 struct iio_buffer *buffer = container_of(ref, struct iio_buffer, ref);
982
983 buffer->access->release(buffer);
984}
985
986/**
987 * iio_buffer_get() - Grab a reference to the buffer
988 * @buffer: The buffer to grab a reference for, may be NULL
989 *
990 * Returns the pointer to the buffer that was passed into the function.
991 */
992struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer)
993{
994 if (buffer)
995 kref_get(&buffer->ref);
996
997 return buffer;
998}
999EXPORT_SYMBOL_GPL(iio_buffer_get);
1000
1001/**
1002 * iio_buffer_put() - Release the reference to the buffer
1003 * @buffer: The buffer to release the reference for, may be NULL
1004 */
1005void iio_buffer_put(struct iio_buffer *buffer)
1006{
1007 if (buffer)
1008 kref_put(&buffer->ref, iio_buffer_release);
1009}
1010EXPORT_SYMBOL_GPL(iio_buffer_put);