only one element get stored in kfifo

chrishell chris at chrishell.de
Tue Oct 11 08:36:20 EDT 2022


hello, Im struggle with a simple kfifo. I try to do it dynamicly. For 
the sake of simplicity I changed the code in a way that everything with 
the kfifo is done in the open function of my module.

First of all, I have a struct, in which I store the pointer to that kfifo:

struct mymod_private_fops {
	wait_queue_head_t    wait;
	struct kfifo         mymod_fifo;
}


And the struct in which I store my data:

struct mymod_data_pkt {
	__u8 	mbyte;
	__u8 	smfunc;
	ktime_t ktime;
	__u16	len;
	__u16	sequence;
	char	devname[32]
	void	*page;
};


this is the open function, which creates the kfifo and stores the 
pointer to that kfifo for later usage. As I mentioned I simplified the 
whole thing to have the store operation into the kfifo and the fetch 
operation, out of the kfifo in one place. Initially I did this in the 
read and write function.

static int mymod_open(struct inode *pinode, struct file *pfile)
{
	int rc  = 0,
	    len = 0;

	struct mymod_private_fops pfops;
	struct mymod_data_pkt w_cache1, w_cache2, w_cache3 r_cache1, r_cache2, 
r_cache3;
	
	pfops = kzalloc(sizeof(struct mymod_private_fops), GFP_KERNEL);

	if(pfops == NULL)
		return -ENOMEM;

	init_waitqueue_head(&pfops->wait);

	len = LOG_STACK_SIZE * sizeof(struct mymod_data_pkt);

	rc = kfifo_alloc(&pfops->mymod_fifo, len, GFP_KERNEL);
	if(rc) {
		pr_err("kfifo_alloc failed %d", rc);
		return rc;
	}

	if(! kfifo_initialized(&pfops->mymod_fifo)) {
		pr_err("kfifo initialized");
	}

	w_cache1.mbyte = 4;
	w_cache1.len   = 245;

	rc = kfifo_in(&pfops->mymod_fifo, &w_cache1, sizeof(struct 
mymod_data_pkt));
	pr_err("kfifo_in returns %d", rc);

	w_cache2.mbyte = 42;
	w_cache2.len   = 112;

	rc = kfifo_in(&pfops->mymod_fifo, &w_cache2, sizeof(struct 
mymod_data_pkt));
	pr_err("kfifo_in returns %d", rc);

	w_cache3.mbyte	= 119;
	w_cache3.len	= 77;

	rc = kfifo_in(&pfops->mymod_fifo, &w_cache3, sizeof(struct 
mymod_data_pkt));
	pr_err("kfifo_in returns %d", rc);

	rc = kfifo_len(&pfops->mymod_fifo);
	pr_err("kfifo_len: %d", rc);

	memset(&r_cache1, 0, sizeof(struct mymod_data_pkt));

	rc = kfifo_get(&pfops->mymod_fifo, &r_cache1);
	pr_err("kfifo_get returns %d", rc);

	pr_err("content of kfifo r_cache1->mbyte: %d", r_cache1.mbyte);

	memset(&r_cache2, 0, sizeof(struct mymod_data_pkt));

	rc = kfifo_get(&pfops->mymod_fifo, &r_cache2);
	pr_err("kfifo_get returns %d", rc);

	pr_err("content of kfifo r_cache2->mbyte: %d", r_cache2.mbyte);

	...

	pfile->private_data = pfops;

	...

[  108.200977] kfifo_in returns 64
[  108.200985] kfifo_in returns 64
[  108.200990] kfifo_in returns 64
[  108.200993] kfifo_len: 192
[  108.200997] kfifo_get returns 1
[  108.201000] content of kfifo r_cache1->mbyte: 4
[  108.201003] kfifo_get returns 1
[  108.201006] content of kfifo r_cache2->mbyte: 0
[  108.201010] kfifo_get returns 1
[  108.201013] content of kfifo r_cache3->mbyte: 0

The initialization worked fine, the store operations went properly. Only 
pulling data out of the kfifo didn't work
  as expected.
Only the 1st element was correct, the 2nd and 3rd element was just 0

Also the size of the struct and the fifo seems to be okay. The struct 
has the size of 64 (there is some padding within I think) and after 
inserting 3 elements the kfifo has the size of 192

Where is the flaw here?


Thank you in advance

Best regards Christian




More information about the Kernelnewbies mailing list