/* * Sample dynamic sized record fifo implementation * * Copyright (C) 2010 Stefani Seibold * * Released under the GPL version 2 only. * */ #include #include #include #include #include /* * This module shows how to create a variable sized record fifo. */ /* fifo size in elements (bytes) */ #define FIFO_SIZE 128 /* name of the proc entry */ #define PROC_FIFO "record-fifo" /* lock for procfs read access */ static DEFINE_MUTEX(read_lock); /* lock for procfs write access */ static DEFINE_MUTEX(write_lock); /* * define DYNAMIC in this example for a dynamically allocated fifo. * * Otherwise the fifo storage will be a part of the fifo structure. */ #if 0 #define DYNAMIC #endif /* * struct kfifo_rec_ptr_1 and STRUCT_KFIFO_REC_1 can handle records of a * length between 0 and 255 bytes. * * struct kfifo_rec_ptr_2 and STRUCT_KFIFO_REC_2 can handle records of a * length between 0 and 65535 bytes. */ #ifdef DYNAMIC struct kfifo_rec_ptr_1 test; #else typedef STRUCT_KFIFO_REC_1(FIFO_SIZE) mytest; static mytest test; #endif static const char *expected_result[] = { "a", "bb", "ccc", "dddd", "eeeee", "ffffff", "ggggggg", "hhhhhhhh", "iiiiiiiii", "jjjjjjjjjj", }; static int __init testfunc(void) { char buf[100]; unsigned int i; unsigned int ret; struct { unsigned char buf[6]; } hello = { "hello" }; printk(KERN_INFO "record fifo test start\n"); kfifo_in(&test, &hello, sizeof(hello)); /* show the size of the next record in the fifo */ printk(KERN_INFO "fifo peek len: %u\n", kfifo_peek_len(&test)); /* put in variable length data */ for (i = 0; i < 10; i++) { memset(buf, 'a' + i, i + 1); kfifo_in(&test, buf, i + 1); } /* skip first element of the fifo */ printk(KERN_INFO "skip 1st element\n"); kfifo_skip(&test); printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test)); /* show the first record without removing from the fifo */ ret = kfifo_out_peek(&test, buf, sizeof(buf)); if (ret) printk(KERN_INFO "%.*s\n", ret, buf); /* check the correctness of all values in the fifo */ i = 0; while (!kfifo_is_empty(&test)) { ret = kfifo_out(&test, buf, sizeof(buf)); buf[ret] = '\0'; printk(KERN_INFO "item = %.*s\n", ret, buf); if (strcmp(buf, expected_result[i++])) { printk(KERN_WARNING "value mismatch: test failed\n"); return -EIO; } } if (i != ARRAY_SIZE(expected_result)) { printk(KERN_WARNING "size mismatch: test failed\n"); return -EIO; } printk(KERN_INFO "test passed\n"); return 0; } static ssize_t fifo_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int ret; unsigned int copied; if (mutex_lock_interruptible(&write_lock)) return -ERESTARTSYS; ret = kfifo_from_user(&test, buf, count, &copied); mutex_unlock(&write_lock); return ret ? ret : copied; } static ssize_t fifo_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { int ret; unsigned int copied; if (mutex_lock_interruptible(&read_lock)) return -ERESTARTSYS; ret = kfifo_to_user(&test, buf, count, &copied); mutex_unlock(&read_lock); return ret ? ret : copied; } static const struct file_operations fifo_fops = { .owner = THIS_MODULE, .read = fifo_read, .write = fifo_write, .llseek = noop_llseek, }; static int __init example_init(void) { #ifdef DYNAMIC int ret; ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL); if (ret) { printk(KERN_ERR "error kfifo_alloc\n"); return ret; } #else INIT_KFIFO(test); #endif if (testfunc() < 0) { #ifdef DYNAMIC kfifo_free(&test); #endif return -EIO; } if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) { #ifdef DYNAMIC kfifo_free(&test); #endif return -ENOMEM; } return 0; } static void __exit example_exit(void) { remove_proc_entry(PROC_FIFO, NULL); #ifdef DYNAMIC kfifo_free(&test); #endif } module_init(example_init); module_exit(example_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Stefani Seibold "); ct>space:mode:
authorChristoph Hellwig <hch@lst.de>2017-01-30 13:15:41 +0100
committerBjorn Helgaas <bhelgaas@google.com>2017-02-02 10:35:46 -0600
commitdfef358bd1beb4e7b5c94eca944be9cd23dfc752 (patch)
treeb9a2afb38a4c2ac8ad31f49ec0d71fe9e5b1994c /sound/soc/codecs/cs35l33.c
parent030305d69fc6963c16003f50d7e8d74b02d0a143 (diff)
PCI/MSI: Don't apply affinity if there aren't enough vectors left
Bart reported a problem wіth an out of bounds access in the low-level IRQ affinity code, which we root caused to the qla2xxx driver assigning all its MSI-X vectors to the pre and post vectors, and not having any left for the actually spread IRQs. Fix this issue by not asking for affinity assignment when there are no vectors to assign left. Fixes: 402723ad5c62 ("PCI/MSI: Provide pci_alloc_irq_vectors_affinity()") Link: https://lkml.kernel.org/r/1485359225.3093.3.camel@sandisk.com Reported-by: Bart Van Assche <bart.vanassche@sandisk.com> Tested-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'sound/soc/codecs/cs35l33.c')