Hi we are having performance issues on the L137 processor using the open source GIT linux version (and Montavista version) on the L137 processor and eval card
Basically we have a driver which receives an interrupt every 125uS into a GPIO line. The interrupt handler wakes up and process waiting on a wait queue. The write call simply puts the calling process to sleep on the wait queue.
I'm toggling a GPIO line in the isr and write call to get an idea of the time spent in IRQ and the time spent in the call to write (the line is asserted when the process is awaoken and deasserted when put to sleep)
I'm making comparisons to something we did similar with an IXP420 255MHz processor running an old 2.4.20 kernel which had no such problems and received two interrupt sources at 8kHz,
I'm concerneed that the OMAP arm has a smaller cache size 16k for instruction and data compared to the IXP425 arm 5 32k, and that the processor / linux is unsuitable.
Below is a full outline of our problems. My concern is that we will not have the power to run our application code.
I apolgise if I've put this on the wrong forum.
Has anyone else had similar experiences with this processor / linux?
Regards
Dave
Full details ....
OMAP L137 / Linux performance issues
Outline of a simple driver / userspace appliction:
Driver wakes up userspace process every 125uS performance is measured by driving gpio line in ISR and driving another line in the context of the write process.
Issues:
ISR and process latency seems to be poor and time spent in the write process (15uS best) context seems to be excessive for what is being done here. The worry is there will be little processing time for our user space application.
Although the process is scheduled as real-time it is affected by other logins and apps such as top.
Shell commands such as PS are a little slow to respond.
Results Summary (Typical):
ISR Latency = 15uS
User Process wakeup Latency =35uS
Time in ISR = 10uS
Time in write process context = 15uS
We have tried the above scenario on the Montavist 2.6.18 kernel shipped with the eval card with PREEMPT_RT enabled, which gives very similar results.
We have very similar processing on a 266MHz IXP420 running linux 2.4.20 (montavista) and 2.6.26 (opensource) which handle this on an existing application (two ISRs at 8kHz rate) with a large multi treaded application on top. No problems running telnet logins etc.
Kernel Config
OMAP opensource GIT Kernel with spi support based on 2.6.37
Built with codesourcery tool chain, running with ramdisk, PREEMPT (low latency desktop), high-res timers, tickless kernel enabled.
Driver:
Sets up McASP 1 to give a 8kHz pulse which is wired into GPIO(0, 13)
Interrupt handler simply wakes up user space process waiting on wait queue.
// Handle a 125uS sync pulse
// . Enable the uart transmitter
// . Set up dma transfer if data is available
// . Set user index of which buffer to write to
// . Wake up tx process
static irqreturn_t sync_handler(int irq, void *dev_id)
{
struct srm600_device_config *dev_config = (struct srm600_device_config *) dev_id;
//gpio_set_value(GPIO_TO_PIN(0,15), 1);
__raw_writel(0x8000, gpio_base_addr + BANK0_SET_OFFSET);
// for test purposes simply wake up the write process so we are scheduling on 120uS
// wake up process waiting on rx
wake_up_interruptible(&dev_config->write_wq);
//gpio_set_value(GPIO_TO_PIN(0,15), 0);
__raw_writel(0x8000, gpio_base_addr + BANK0_CLR_OFFSET);
return IRQ_HANDLED;
}
Write process is put to sleep awaiting wake up
static ssize_t srm600_uart_write (struct file *filp, char *buf, size_t count,
loff_t *f_pos)
{
DEFINE_WAIT(wait);
struct srm600_device_config *dev_config = (struct srm600_device_config *) filp->private_data;
#if 0
gpio_set_value(GPIO_TO_PIN(0,12), 0);
#else
__raw_writel(0x1000, gpio_base_addr + BANK0_CLR_OFFSET);
#endif
prepare_to_wait(&dev_config->write_wq, &wait, TASK_INTERRUPTIBLE);
schedule();
finish_wait(&dev_config->write_wq, &wait);
#if 0
gpio_set_value(GPIO_TO_PIN(0,12), 1);
#else
__raw_writel(0x1000, gpio_base_addr + BANK0_SET_OFFSET);
#endif
return count;
}
Userspace
Write thread simply loops and prints out a message every 1 second
while(!exitting)
{
if(write(fd, txbuffer, strlen(txbuffer) +1) > 0)
{
txcount++;
if(txcount == 8000)
{
txcount = 0;
printf("Write woken 8000x\n");
}
#ifdef ADD_DELAY
for(z=0; z< 400;z++)
{
t = z;
}
#endif
}
else
{
printf("Error writing to uart\n");
}
}
Thread is started as a real-time process
#ifdef REAL_TIME
pthread_attr_init(&attr);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
schedp.sched_priority = 99;
pthread_attr_setschedparam(&attr, &schedp);
pthread_create(&txthread, &attr, processTx, NULL);
pthread_attr_destroy(&attr);
#else
pthread_create(&txthread, NULL, processTx, NULL);
#endif