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 >