dma_ip_drivers icon indicating copy to clipboard operation
dma_ip_drivers copied to clipboard

[XDMA] always get IRQ by calling poll() /dev/xdma0_event_0 even when no IRQ occurs

Open vutang opened this issue 6 years ago • 4 comments

With this code, poll() function will return even when no IRQ occurs.

struct pollfd pfd;
pfd.fd = open("/dev/xdma0_events_0", O_RDONLY);
if (pfd.fd == -1) {
	perror("open event file:");
	exit(EXIT_FAILURE);
}
pfd.events = POLLIN | POLLRDNORM;

while (1) {
	ret = poll(&pfd, 1, 2000); /*Timeout: 2000 ms*/
	if (ret == -1) {
		perror("poll:");
		break;
	}
	if (!ret) {
		printf("timeout %d\n", irq_prof->id);
		break;
	}
	if ((pfd.revents & POLLRDNORM) || (pfd.revents & POLLIN)) {
		hw_counter = *(usr_int_ptr + 4 * irq_prof->id + 3);
		irq_counter++;
		printf("IRQ%d, %d, %d, %d\n", \
			irq_prof->id, hw_counter, irq_counter, hw_counter - irq_counter);
	}
}

So to fix this issue, we add a line to poll() in cdev_events.c.

spin_lock_irqsave(&user_irq->events_lock, flags);
if (user_irq->events_irq)
	mask = POLLIN | POLLRDNORM;	/* readable */
user_irq->events_irq = 0; /*new*/
spin_unlock_irqrestore(&user_irq->events_lock, flags);

vutang avatar Sep 21 '19 04:09 vutang

Hi Vu Tang,

I am not sure if this is a bug or if poll is intended for some other use case. We ran into the same problem and I do not really understand the purpose of poll() as it is. However, there is an easy solution. You can use the read() function to get what you want. The read() function will (in the kernel driver) wait for an interrupt or until somebody wakes it. In case of an interrupt, it will then clear the interrupt and return to the user. It will also return a buffer with the index of the user_irq which was received.

The poll function is similar, but it seems like it does not clear the interrupt. At least that is how I remember it.

Best regards

amue84 avatar May 14 '20 15:05 amue84

Hi Vu Tang,

I am not sure if this is a bug or if poll is intended for some other use case. We ran into the same problem and I do not really understand the purpose of poll() as it is. However, there is an easy solution. You can use the read() function to get what you want. The read() function will (in the kernel driver) wait for an interrupt or until somebody wakes it. In case of an interrupt, it will then clear the interrupt and return to the user. It will also return a buffer with the index of the user_irq which was received.

The poll function is similar, but it seems like it does not clear the interrupt. At least that is how I remember it.

Best regards

Hi @amue84,

I have already updated my commented. We have already fixed this issue.

vutang avatar Oct 22 '20 08:10 vutang

Hello,

My name is Mark Harfouche. I am not affiliated with Xilinx in any way. Over the years of using QDMA, I've been wanted better community organization.

I've created a fork of dma_ip_drivers which I intend to maintain and work with the community at large to improve.

The fork can be found https://github.com/hmaarrfk/dma_ip_drivers

For now, I am stating the main goals of the repository in https://github.com/hmaarrfk/dma_ip_drivers/issues/2

If you are interested in working together, feel free to open an issue or PR to my fork.

Best,

Mark

hmaarrfk avatar Aug 22 '22 04:08 hmaarrfk

Hello,

My name is Mark Harfouche. I am not affiliated with Xilinx in any way. Over the years of using QDMA, I've been wanted better community organization.

I've created a fork of dma_ip_drivers which I intend to maintain and work with the community at large to improve.

The fork can be found https://github.com/hmaarrfk/dma_ip_drivers

For now, I am stating the main goals of the repository in hmaarrfk#2

If you are interested in working together, feel free to open an issue or PR to my fork.

Best,

Mark

Hi Mark,

What did you do with QDMA? Can you share?

Regards Vu Tang

vutang avatar Nov 30 '22 08:11 vutang