Hi, I am having data race from threadsanitizer report.
Could you see if there is still data race in the following code using ptr_ring API ? /* * Filename: circ_ring.c * Version: 1.0 * Description: A circular buffer using API from * https://github.com/torvalds/linux/blob/master/include/linux/ptr_ring.h */ #include <linux/slab.h> #include <linux/mm.h> #include <linux/ptr_ring.h> #include "circ_ring.h" //#include <assert.h> #define DEBUG 1 #ifdef DEBUG #define DEBUG_MSG(...) printk(__VA_ARGS__) #else #define DEBUG_MSG(...) #endif struct ptr_ring * init_circ_queue(int len) { struct ptr_ring * q; q = kzalloc(sizeof(struct ptr_ring), GFP_KERNEL); if (q == NULL) { DEBUG_MSG(KERN_ERR "Not enough memory to allocate ptr_ring"); return NULL; } // creates an array of length 'len' where each array location can store a struct * item if(ptr_ring_init(q, len, GFP_KERNEL) != 0) { DEBUG_MSG(KERN_ERR "Not enough memory to allocate ptr_ring array"); return NULL; } return q; } inline int push_circ_queue(struct ptr_ring * buffer, struct item * item_push) { /* insert one item into the buffer */ if(ptr_ring_produce_any(buffer, item_push) == 0) // operation is successful { DEBUG_MSG(KERN_INFO "Successfully pushed val1 = %u and val2 = %u\n", item_push->val1, item_push->val2); return 0; } else { DEBUG_MSG(KERN_INFO "full, not enough buffer space\n"); return 1; } } inline int pop_circ_queue(struct ptr_ring * buffer, struct item * item_pop) { struct item * item_temp = 0; /* extract one item struct containing two unsigned integers from the buffer */ item_temp = (struct item *)ptr_ring_consume_any(buffer); if(item_temp) // (!= NULL) { item_pop->val1 = item_temp->val1; item_pop->val2 = item_temp->val2; // val1 will never be zero since the event number starts from 1 (so, val1 in push_circ_queue() will not be zero, same case after pop_circ_queue()), and 0 is only possible during initialization, not during pop_circ_queue() //assert(item_pop->val1 != 0); DEBUG_MSG(KERN_INFO "Before pop, head = %u , tail = %u\n", buffer->consumer_head, buffer->consumer_tail); DEBUG_MSG(KERN_INFO "val1 = %u , val2 = %u\n", item_pop->val1, item_pop->val2); DEBUG_MSG(KERN_INFO "After pop, head = %u , tail = %u\n", buffer->consumer_head, buffer->consumer_tail); return 0; } else { //DEBUG_MSG(KERN_INFO "empty, nothing to pop from the ring\n"); return 1; } } void free_circ_queue(struct ptr_ring * q) { ptr_ring_cleanup(q, NULL); } Regards, Phung