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;
}