Re: Unexpected high latency on bbb

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2/20/20, Laurentiu-Cristian Duca <laurentiu.duca@xxxxxxxxx> wrote:
> Hello,
>
>   I have made a rt-test on kernel preempt-rt 5.4.5
> and got unexpected high latencies (5ms max).
> Maybe I am doing something wrong ... please help
> The same test got 120us max latency on EVL project
> (on 3 hour test with one million samples)
> and only the synchronization is different on preempt_rt
> (referring to rt_gpio module described below).
>
> scenario between beaglebone black computer and fpga board
> ====
> fpga generates an interrupt and counts latency until ack
> bbb receives and ack interrupt via rt_gpio module
> fpga sends latency counter value via SPI to bbb
> bbb prints on the screen
> result: 5ms max latency.
>
> rt_gpio.c module
> ====
> ...
> static struct swait_queue_head head_swait;
>
> static irqreturn_t rt_interrupt_handler(int irq, void *data)
> {
> 	n_interrupts++;
>
> 	/* use swait.h model to signal interrupt arrived */
> 	interrupt_done = 1;
> 	smp_mb();
>  	if (swait_active(&head_swait))
> 		swake_up_one(&head_swait);
>
> 	return IRQ_HANDLED;
> }
>
> static ssize_t rt_gpio_read(struct file *f, char __user *buf, size_t
> 	len, loff_t *off)
> {
> 	int ret;
> 	DECLARE_SWAITQUEUE(swait);
>
> 	/* wait for interrupt using swait.h model */
> 	for (;;) {
> 		prepare_to_swait_exclusive(&head_swait, &swait, TASK_INTERRUPTIBLE);
>  		/* smp_mb() from set_current_state() */
>  		if (interrupt_done)
>  			break;
>  		schedule();
>  	}
> 	finish_swait(&head_swait, &swait);
> 	interrupt_done = 0;
> 	smp_mb();
> 	
> 	gpiod_get_raw_value(gpiod_in)
> 	copy_to_user(...);
> }
>
> static ssize_t rt_gpio_write(struct file *f, const char __user *buf,
> 	size_t len, loff_t *off)
> {
>     copy_from_user(...);
> 	gpiod_set_raw_value(gpiod_out, user_value);
> }
>
> static int __init rt_gpio_init(void) /* Constructor */
> {
> 	...
> 	request_irq(irq_line, rt_interrupt_handler,
> 		IRQ_TYPE_EDGE_RISING | IRQF_NO_THREAD, "rt_gpio interrupt\n", (void
> *)1));
>
> 	init_swait_queue_head(&head_swait);
> 	
> }
>
> static void __exit rt_gpio_exit(void)
> {
> 	free_irq(irq_line, (void*)1);
> 	gpio_free(gpio_in_id);
> 	gpio_free(gpio_out_id);
> 	...
> }
>
>
> userspace
> ====
>     printf("Setup this thread as a real time thread\n");
>   	if((ret = mlockall(MCL_FUTURE|MCL_CURRENT)) < 0) {
>        	printf("mlockall failed: %s\n", strerror(ret));
>        	return -1;
>    	}
>     sp.sched_priority = 98;
>     if((ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) != 0)
> {
>         printf("Failed to set lat thread to real-time priority: %s\n",
> strerror(ret));
> 		return -1;
>     }

the mistake was corrected by calling:
	sched_setscheduler(getpid(), SCHED_FIFO, &sp);


>     ...
>     use rt_gpio module to receive interrupt and ack.
>
>
>
> Thank you,
> L-C
>



[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux