Hi,
We are currently running into a performance issue with the DM8147 using linux DVR-RDK (2.6.37).
This prevents us from doing our periodic processing within a reasonable window of determinism. From our investigations, we have determined that the ethernet (cpsw) driver is somehow hogging the processor.
Is this a known issue when using DVR-RDK?
Details....
I've written a simplified version of our driver/userspace application that I used to reproduce the problem (code below).
The driver wakes up the userspace RT thread every 20ms. The performance is measured by driving gpio[27] in the isr and driving gpio[28] in the context of the RT thread process.
Issue:
The wake up is often delayed by multiple ms ( sometimes up to 180 ms) if we have an Ethernet cable connected. If we unconnect the Ethernet cable we can run for multiple days without any problems.
Typical Latency:
ISR: 10 us
Wake Up RT Thread: 18 us <<< This is what gets affected by using Ethernet or not
Driver Code
static irqreturn_t isr(int irq, void *device) { gpio_set_value(27, 1); gpio_set_value(27, 0); if (atomic_read(&device_data->awake) == 0) // Someone sleeping on it? { atomic_set(&device_data->awake, 1); wake_up_interruptible(&device_data->irqWaitq); } else { // Bad: irq was flagged by fpga no one was waiting to catch it. device_data->irqUnservicedCount++; printk("%s(): %d LOST IRQ\n", __FUNCTION__, device_data->irqUnservicedCount); } return IRQ_HANDLED; }
static unsigned int device_poll(struct file *filp, struct poll_table_struct * wait) { unsigned int mask = 0; poll_wait(filp, &device_data->irqWaitq, wait); mutex_lock(&device_data->lock); if(atomic_read(&device_data->awake) == 1) { gpio_set_value(28, 1); mask |= POLLIN | POLLRDNORM; atomic_set(&device_data->awake, 0); } else { gpio_set_value(28, 0); } mutex_unlock(&device_data->lock); return mask; }
Userspace Application
bool end_thread = false; const char *dev_name = "/dev/irq_issue"; void *executeThread(void *arg) { struct sched_param param; param.sched_priority = sched_get_priority_max(SCHED_FIFO); pthread_setschedparam( pthread_self(), SCHED_FIFO, ¶m); dev_t dev = makedev(233, 0); mknod(dev_name, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, dev); int fd = open(dev_name, O_RDWR); struct pollfd poll_fd; poll_fd.fd = fd; poll_fd.events = POLLIN; poll_fd.revents = 0; while (!end_thread) { poll(&poll_fd, 1, -1); }; close(fd); return NULL; } int main(void) { pthread_t thread_id; pthread_create(&thread_id, NULL, executeThread, NULL); pthread_join(thread_id, NULL); return 0; }