Discussion:
[Rtai] (no subject)
Guo Yunfei
2018-06-17 08:11:00 UTC
Permalink
Hi, everyone:

I'm face the problem of rt_sem_signal() low efficiency.

I register my PCI interrupt handler by:
rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev);

the interrupt handler code is:

static irqreturn_t my_isr(int irq, void *data)
{
struct my_device *dev = data;

unsigned short LINTSR; //LINTSR:local interrupt status register;
int iIntSource = 0;
LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status

if (LINTSR & 0x1) {
iIntSource = ReadIntSource(); //check the interrupt source.
if((iIntSource & 0x1) == 0x1) {
ClearInterruptFunc();
shm_ptr->IntType = 1;//Flag_ISR;
}

volatile RTIME t1, t2, t_elapsed; //check the rt_sem_signal()
elapse time
t1 = rt_get_cpu_time_ns();
rt_sem_signal(&sem);
t2 = rt_get_cpu_time_ns();
t_elapsed = (t2 - t1);

//printk(" %d \n",t_elapsed);
writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt ;
}
return IRQ_HANDLED;
}

Then, I implement the real isr work in user space LXRT method like below,
for I want enjoy the convinience of user space driver developing.

static int Answer_irq()
{
if (!(irqtask = rt_thread_init(nam2num("ANSWERIRQTSK"), 0, 0,
SCHED_FIFO, 0x0))) {
printf("CANNOT INIT PROCESS ANSWERIRQTSK\n");
exit(1);
}
mlockall(MCL_CURRENT | MCL_FUTURE);

rt_make_hard_real_time();
while (1) {
rt_sem_wait(sem);
switch (shm_ptr->IntType)
{
case 1:
REAL_ISR(); //the real isr working here.
break;
return 0;
}
}
rt_make_soft_real_time();
rt_task_delete(irqtask);
return 0;
}

This mechanism can working smooth, but,its efficiency is much lower.
around 33% slower than that directly runing the REAL_ISR() in kernel space
interrupt handler(codes as below)

static irqreturn_t my_isr(int irq, void *data)
{
struct my_device *dev = data;

unsigned short LINTSR; //LINTSR:local interrupt status register;
int iIntSource = 0;
LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status

if (LINTSR & 0x1) {
iIntSource = ReadIntSource(); //check the interrupt source.
if((iIntSource & 0x1) == 0x1) {
clearInterruptFunc();
REAL_ISR(); // real isr working in interrupt handler
}

writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt ;
}
return IRQ_HANDLED;
}

So, I suspect rt_sem_signal(&sem) give much delay in this mechanism.
my rt_sem_signal(&sem) elapse time dmesg segment like below:
[ 198.234668] 1738
[ 198.235488] 4988
[ 198.236308] 913
[ 198.237128] 8038
[ 198.237945] 1625
[ 198.238764] 5038
[ 198.239584] 912
[ 198.240404] 3750
[ 198.241222] 1575
[ 198.242042] 5275
[ 198.242866] 2025
[ 198.243690] 11976
[ 198.244498] 1662
[ 198.245317] 5125
[ 198.246137] 875
[ 198.246959] 8201
[ 198.247774] 1612
[ 198.248593] 8351
[ 198.249413] 725
[ 198.250234] 7714
[ 198.251051] 1625
[ 198.251871] 5125
[ 198.252691] 1350
[ 198.253513] 8087
[ 198.254329] 1775
[ 198.255147] 8662
[ 198.255966] 813
[ 198.256787] 7387
[ 198.257604] 1525
[ 198.258429] 4725
[ 198.259266] 15699
[ 198.260064] 5362
[ 198.260882] 1562
[ 198.261707] 4975
[ 198.262540] 15750
[ 198.263346] 6388
[ 198.264160] 2063
[ 198.264987] 2337
[ 198.265822] 16974
[ 198.266625] 6350
[ 198.267442] 2475
[ 198.268268] 2350
[ 198.269084] 11675

Is this normal? (My platform is Intel® Celeron N3160,1.6 GHz (Quad-Core)).
Or, any suggestion for my problem to raise its IPC efficiency?


Thanks in advance.

Guo Yunfei
Paolo Mantegazza
2018-06-17 20:59:54 UTC
Permalink
As a further comment, I would say that, seeing a worst case latency of 17 us for an RTAI real time task waiting for a semaphore, very likely signalling from within the Linux environment, is a quite good result.

Moreover take into account that you are measuring not only you isr processing time but a whole double task switching. The second one being, likely again, a Linux task wake up.

Paolo.

________________________________________
From: Paolo Mantegazza
Sent: Sunday, June 17, 2018 10:37 PM
To: Guo Yunfei; ***@rtai.org
Subject: RE: [Rtai] (no subject)

????? rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev); ?????
You are trying to menage a Linux interrupt using an RTAI hard real time task.
No surprise of a reduced efficiency. If you want to carry out real time interrupt handling in user space try rtai_usi.
The whole stuff will be crried otu in user space.

Nonetheless, if you want to have a kernel handler, waking an RTAI hard real time task in user space, register a native RTAI handler.

Paolo

________________________________________
From: Rtai [rtai-***@rtai.org] on behalf of Guo Yunfei [***@gmail.com]
Sent: Sunday, June 17, 2018 10:11 AM
To: ***@rtai.org
Subject: [Rtai] (no subject)

Hi, everyone:

I'm face the problem of rt_sem_signal() low efficiency.

I register my PCI interrupt handler by:
rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev);

the interrupt handler code is:

static irqreturn_t my_isr(int irq, void *data)
{
struct my_device *dev = data;

unsigned short LINTSR; //LINTSR:local interrupt status register;
int iIntSource = 0;
LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status

if (LINTSR & 0x1) {
iIntSource = ReadIntSource(); //check the interrupt source.
if((iIntSource & 0x1) == 0x1) {
ClearInterruptFunc();
shm_ptr->IntType = 1;//Flag_ISR;
}

volatile RTIME t1, t2, t_elapsed; //check the rt_sem_signal() elapse time
t1 = rt_get_cpu_time_ns();
rt_sem_signal(&sem);
t2 = rt_get_cpu_time_ns();
t_elapsed = (t2 - t1);

//printk(" %d \n",t_elapsed);
writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt ;
}
return IRQ_HANDLED;
}

Then, I implement the real isr work in user space LXRT method like below, for I want enjoy the convinience of user space driver developing.

static int Answer_irq()
{
if (!(irqtask = rt_thread_init(nam2num("ANSWERIRQTSK"), 0, 0, SCHED_FIFO, 0x0))) {
printf("CANNOT INIT PROCESS ANSWERIRQTSK\n");
exit(1);
}
mlockall(MCL_CURRENT | MCL_FUTURE);

rt_make_hard_real_time();
while (1) {
rt_sem_wait(sem);
switch (shm_ptr->IntType)
{
case 1:
REAL_ISR(); //the real isr working here.
break;
return 0;
}
}
rt_make_soft_real_time();
rt_task_delete(irqtask);
return 0;
}

This mechanism can working smooth, but,its efficiency is much lower.
around 33% slower than that directly runing the REAL_ISR() in kernel space interrupt handler(codes as below)

static irqreturn_t my_isr(int irq, void *data)
{
struct my_device *dev = data;

unsigned short LINTSR; //LINTSR:local interrupt status register;
int iIntSource = 0;
LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status

if (LINTSR & 0x1) {
iIntSource = ReadIntSource(); //check the interrupt source.
if((iIntSource & 0x1) == 0x1) {
clearInterruptFunc();
REAL_ISR(); // real isr working in interrupt handler
}

writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt ;
}
return IRQ_HANDLED;
}

So, I suspect rt_sem_signal(&sem) give much delay in this mechanism.
my rt_sem_signal(&sem) elapse time dmesg segment like below:
[ 198.234668] 1738
[ 198.235488] 4988
[ 198.236308] 913
[ 198.237128] 8038
[ 198.237945] 1625
[ 198.238764] 5038
[ 198.239584] 912
[ 198.240404] 3750
[ 198.241222] 1575
[ 198.242042] 5275
[ 198.242866] 2025
[ 198.243690] 11976
[ 198.244498] 1662
[ 198.245317] 5125
[ 198.246137] 875
[ 198.246959] 8201
[ 198.247774] 1612
[ 198.248593] 8351
[ 198.249413] 725
[ 198.250234] 7714
[ 198.251051] 1625
[ 198.251871] 5125
[ 198.252691] 1350
[ 198.253513] 8087
[ 198.254329] 1775
[ 198.255147] 8662
[ 198.255966] 813
[ 198.256787] 7387
[ 198.257604] 1525
[ 198.258429] 4725
[ 198.259266] 15699
[ 198.260064] 5362
[ 198.260882] 1562
[ 198.261707] 4975
[ 198.262540] 15750
[ 198.263346] 6388
[ 198.264160] 2063
[ 198.264987] 2337
[ 198.265822] 16974
[ 198.266625] 6350
[ 198.267442] 2475
[ 198.268268] 2350
[ 198.269084] 11675

Is this normal? (My platform is Intel® Celeron N3160,1.6 GHz (Quad-Core)).
Or, any suggestion for my problem to raise its IPC efficiency?


Thanks in advance.

Guo Yunfei
Guo Yunfei
2018-06-18 08:15:00 UTC
Permalink
Paolo:

I changed to register my interrupt handler by:

rt_request_irq(pdev->irq, my_isr, "my_pci_device", dev);

the IPC mechanism can working, but the efficiency looks worse more.

then demsg segment as below:

[ 4484.276220] 2512
[ 4484.277046] 3351
[ 4484.277851] 3200
[ 4484.278728] 34514
[ 4484.279478] 2813
[ 4484.280326] 10474
[ 4484.281142] 3125
[ 4484.282003] 9376
[ 4484.282777] 2950
[ 4484.283604] 7075
[ 4484.284419] 3151
[ 4484.285245] 9288
[ 4484.286042] 3024
[ 4484.286881] 6937
[ 4484.287670] 3300
[ 4484.288607] 9899
[ 4484.289305] 2650
[ 4484.290157] 7537
[ 4484.290972] 3462
[ 4484.291832] 9526
[ 4484.292608] 3000
[ 4484.293431] 33264
[ 4484.294237] 3250
[ 4484.295090] 9414
[ 4484.295863] 2863
[ 4484.296712] 7013
[ 4484.297498] 28501
[ 4484.298388] 9774
[ 4484.299161] 2962
[ 4484.299984] 6512
[ 4484.300800] 3399
[ 4484.301643] 9389
[ 4484.302430] 3063
[ 4484.303262] 6588
[ 4484.304057] 3363
[ 4484.304905] 9250
[ 4484.305689] 27688
[ 4484.306543] 3475
[ 4484.307352] 3212
[ 4484.308211] 9624
[ 4484.308994] 2538
[ 4484.309847] 8012
[ 4484.310621] 3263
[ 4484.311485] 9751
[ 4484.312248] 2750
[ 4484.313063] 3388
[ 4484.313882] 28389
[ 4484.314749] 10601

Can you give me suggestion how to solve this?

Best Regards
Guo Yunfei.

On Mon, Jun 18, 2018 at 4:59 AM, Paolo Mantegazza <
***@polimi.it> wrote:

> As a further comment, I would say that, seeing a worst case latency of 17
> us for an RTAI real time task waiting for a semaphore, very likely
> signalling from within the Linux environment, is a quite good result.
>
> Moreover take into account that you are measuring not only you isr
> processing time but a whole double task switching. The second one being,
> likely again, a Linux task wake up.
>
> Paolo.
>
> ________________________________________
> From: Paolo Mantegazza
> Sent: Sunday, June 17, 2018 10:37 PM
> To: Guo Yunfei; ***@rtai.org
> Subject: RE: [Rtai] (no subject)
>
> ????? rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev); ?????
> You are trying to menage a Linux interrupt using an RTAI hard real time
> task.
> No surprise of a reduced efficiency. If you want to carry out real time
> interrupt handling in user space try rtai_usi.
> The whole stuff will be crried otu in user space.
>
> Nonetheless, if you want to have a kernel handler, waking an RTAI hard
> real time task in user space, register a native RTAI handler.
>
> Paolo
>
> ________________________________________
> From: Rtai [rtai-***@rtai.org] on behalf of Guo Yunfei [
> ***@gmail.com]
> Sent: Sunday, June 17, 2018 10:11 AM
> To: ***@rtai.org
> Subject: [Rtai] (no subject)
>
> Hi, everyone:
>
> I'm face the problem of rt_sem_signal() low efficiency.
>
> I register my PCI interrupt handler by:
> rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev);
>
> the interrupt handler code is:
>
> static irqreturn_t my_isr(int irq, void *data)
> {
> struct my_device *dev = data;
>
> unsigned short LINTSR; //LINTSR:local interrupt status register;
> int iIntSource = 0;
> LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status
>
> if (LINTSR & 0x1) {
> iIntSource = ReadIntSource(); //check the interrupt source.
> if((iIntSource & 0x1) == 0x1) {
> ClearInterruptFunc();
> shm_ptr->IntType = 1;//Flag_ISR;
> }
>
> volatile RTIME t1, t2, t_elapsed; //check the rt_sem_signal()
> elapse time
> t1 = rt_get_cpu_time_ns();
> rt_sem_signal(&sem);
> t2 = rt_get_cpu_time_ns();
> t_elapsed = (t2 - t1);
>
> //printk(" %d \n",t_elapsed);
> writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt ;
> }
> return IRQ_HANDLED;
> }
>
> Then, I implement the real isr work in user space LXRT method like below,
> for I want enjoy the convinience of user space driver developing.
>
> static int Answer_irq()
> {
> if (!(irqtask = rt_thread_init(nam2num("ANSWERIRQTSK"), 0, 0,
> SCHED_FIFO, 0x0))) {
> printf("CANNOT INIT PROCESS ANSWERIRQTSK\n");
> exit(1);
> }
> mlockall(MCL_CURRENT | MCL_FUTURE);
>
> rt_make_hard_real_time();
> while (1) {
> rt_sem_wait(sem);
> switch (shm_ptr->IntType)
> {
> case 1:
> REAL_ISR(); //the real isr working here.
> break;
> return 0;
> }
> }
> rt_make_soft_real_time();
> rt_task_delete(irqtask);
> return 0;
> }
>
> This mechanism can working smooth, but,its efficiency is much lower.
> around 33% slower than that directly runing the REAL_ISR() in kernel
> space interrupt handler(codes as below)
>
> static irqreturn_t my_isr(int irq, void *data)
> {
> struct my_device *dev = data;
>
> unsigned short LINTSR; //LINTSR:local interrupt status register;
> int iIntSource = 0;
> LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status
>
> if (LINTSR & 0x1) {
> iIntSource = ReadIntSource(); //check the interrupt source.
> if((iIntSource & 0x1) == 0x1) {
> clearInterruptFunc();
> REAL_ISR(); // real isr working in interrupt handler
> }
>
> writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt ;
> }
> return IRQ_HANDLED;
> }
>
> So, I suspect rt_sem_signal(&sem) give much delay in this mechanism.
> my rt_sem_signal(&sem) elapse time dmesg segment like below:
> [ 198.234668] 1738
> [ 198.235488] 4988
> [ 198.236308] 913
> [ 198.237128] 8038
> [ 198.237945] 1625
> [ 198.238764] 5038
> [ 198.239584] 912
> [ 198.240404] 3750
> [ 198.241222] 1575
> [ 198.242042] 5275
> [ 198.242866] 2025
> [ 198.243690] 11976
> [ 198.244498] 1662
> [ 198.245317] 5125
> [ 198.246137] 875
> [ 198.246959] 8201
> [ 198.247774] 1612
> [ 198.248593] 8351
> [ 198.249413] 725
> [ 198.250234] 7714
> [ 198.251051] 1625
> [ 198.251871] 5125
> [ 198.252691] 1350
> [ 198.253513] 8087
> [ 198.254329] 1775
> [ 198.255147] 8662
> [ 198.255966] 813
> [ 198.256787] 7387
> [ 198.257604] 1525
> [ 198.258429] 4725
> [ 198.259266] 15699
> [ 198.260064] 5362
> [ 198.260882] 1562
> [ 198.261707] 4975
> [ 198.262540] 15750
> [ 198.263346] 6388
> [ 198.264160] 2063
> [ 198.264987] 2337
> [ 198.265822] 16974
> [ 198.266625] 6350
> [ 198.267442] 2475
> [ 198.268268] 2350
> [ 198.269084] 11675
>
> Is this normal? (My platform is Intel® Celeron N3160,1.6 GHz (Quad-Core)).
> Or, any suggestion for my problem to raise its IPC efficiency?
>
>
> Thanks in advance.
>
> Guo Yunfei
>
>
>
>
>
>
>
>
>
Guo Yunfei
2018-06-18 08:36:18 UTC
Permalink
And , I even enable the option of:
Disable immediate rescheduling from within ISRs

according to your mailing list thread of
http://mail.rtai.org/pipermail/rtai/2015-January/026651.html

but still low efficiency in my IPC mechanism.

On Mon, Jun 18, 2018 at 4:59 AM, Paolo Mantegazza <
***@polimi.it> wrote:

> As a further comment, I would say that, seeing a worst case latency of 17
> us for an RTAI real time task waiting for a semaphore, very likely
> signalling from within the Linux environment, is a quite good result.
>
> Moreover take into account that you are measuring not only you isr
> processing time but a whole double task switching. The second one being,
> likely again, a Linux task wake up.
>
> Paolo.
>
> ________________________________________
> From: Paolo Mantegazza
> Sent: Sunday, June 17, 2018 10:37 PM
> To: Guo Yunfei; ***@rtai.org
> Subject: RE: [Rtai] (no subject)
>
> ????? rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev); ?????
> You are trying to menage a Linux interrupt using an RTAI hard real time
> task.
> No surprise of a reduced efficiency. If you want to carry out real time
> interrupt handling in user space try rtai_usi.
> The whole stuff will be crried otu in user space.
>
> Nonetheless, if you want to have a kernel handler, waking an RTAI hard
> real time task in user space, register a native RTAI handler.
>
> Paolo
>
> ________________________________________
> From: Rtai [rtai-***@rtai.org] on behalf of Guo Yunfei [
> ***@gmail.com]
> Sent: Sunday, June 17, 2018 10:11 AM
> To: ***@rtai.org
> Subject: [Rtai] (no subject)
>
> Hi, everyone:
>
> I'm face the problem of rt_sem_signal() low efficiency.
>
> I register my PCI interrupt handler by:
> rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev);
>
> the interrupt handler code is:
>
> static irqreturn_t my_isr(int irq, void *data)
> {
> struct my_device *dev = data;
>
> unsigned short LINTSR; //LINTSR:local interrupt status register;
> int iIntSource = 0;
> LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status
>
> if (LINTSR & 0x1) {
> iIntSource = ReadIntSource(); //check the interrupt source.
> if((iIntSource & 0x1) == 0x1) {
> ClearInterruptFunc();
> shm_ptr->IntType = 1;//Flag_ISR;
> }
>
> volatile RTIME t1, t2, t_elapsed; //check the rt_sem_signal()
> elapse time
> t1 = rt_get_cpu_time_ns();
> rt_sem_signal(&sem);
> t2 = rt_get_cpu_time_ns();
> t_elapsed = (t2 - t1);
>
> //printk(" %d \n",t_elapsed);
> writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt ;
> }
> return IRQ_HANDLED;
> }
>
> Then, I implement the real isr work in user space LXRT method like below,
> for I want enjoy the convinience of user space driver developing.
>
> static int Answer_irq()
> {
> if (!(irqtask = rt_thread_init(nam2num("ANSWERIRQTSK"), 0, 0,
> SCHED_FIFO, 0x0))) {
> printf("CANNOT INIT PROCESS ANSWERIRQTSK\n");
> exit(1);
> }
> mlockall(MCL_CURRENT | MCL_FUTURE);
>
> rt_make_hard_real_time();
> while (1) {
> rt_sem_wait(sem);
> switch (shm_ptr->IntType)
> {
> case 1:
> REAL_ISR(); //the real isr working here.
> break;
> return 0;
> }
> }
> rt_make_soft_real_time();
> rt_task_delete(irqtask);
> return 0;
> }
>
> This mechanism can working smooth, but,its efficiency is much lower.
> around 33% slower than that directly runing the REAL_ISR() in kernel
> space interrupt handler(codes as below)
>
> static irqreturn_t my_isr(int irq, void *data)
> {
> struct my_device *dev = data;
>
> unsigned short LINTSR; //LINTSR:local interrupt status register;
> int iIntSource = 0;
> LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status
>
> if (LINTSR & 0x1) {
> iIntSource = ReadIntSource(); //check the interrupt source.
> if((iIntSource & 0x1) == 0x1) {
> clearInterruptFunc();
> REAL_ISR(); // real isr working in interrupt handler
> }
>
> writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt ;
> }
> return IRQ_HANDLED;
> }
>
> So, I suspect rt_sem_signal(&sem) give much delay in this mechanism.
> my rt_sem_signal(&sem) elapse time dmesg segment like below:
> [ 198.234668] 1738
> [ 198.235488] 4988
> [ 198.236308] 913
> [ 198.237128] 8038
> [ 198.237945] 1625
> [ 198.238764] 5038
> [ 198.239584] 912
> [ 198.240404] 3750
> [ 198.241222] 1575
> [ 198.242042] 5275
> [ 198.242866] 2025
> [ 198.243690] 11976
> [ 198.244498] 1662
> [ 198.245317] 5125
> [ 198.246137] 875
> [ 198.246959] 8201
> [ 198.247774] 1612
> [ 198.248593] 8351
> [ 198.249413] 725
> [ 198.250234] 7714
> [ 198.251051] 1625
> [ 198.251871] 5125
> [ 198.252691] 1350
> [ 198.253513] 8087
> [ 198.254329] 1775
> [ 198.255147] 8662
> [ 198.255966] 813
> [ 198.256787] 7387
> [ 198.257604] 1525
> [ 198.258429] 4725
> [ 198.259266] 15699
> [ 198.260064] 5362
> [ 198.260882] 1562
> [ 198.261707] 4975
> [ 198.262540] 15750
> [ 198.263346] 6388
> [ 198.264160] 2063
> [ 198.264987] 2337
> [ 198.265822] 16974
> [ 198.266625] 6350
> [ 198.267442] 2475
> [ 198.268268] 2350
> [ 198.269084] 11675
>
> Is this normal? (My platform is Intel® Celeron N3160,1.6 GHz (Quad-Core)).
> Or, any suggestion for my problem to raise its IPC efficiency?
>
>
> Thanks in advance.
>
> Guo Yunfei
>
>
>
>
>
>
>
>
>
Paolo Mantegazza
2018-06-18 09:31:31 UTC
Permalink
Disabling immediate rescheduling is not what you should do. It lock the
scheduler till you exited all real time interrupts have been processed.
If you are sure to have completed processing your interaction with your
device you should enable it.

Take into account that the way you have tested it is nothing but another
kind of latency test.
Therefore you are getting the very same figures of any similar test.
Moreover, because you cannot be sure that your executions are exactly
the same at different times, nothing can be said by looking at you results.

That said RTAI has its structured way to develop user space interrupt
handlers. It is not much dissimilar from yours, but does not require
anything in kernel space and can provide the closest environment to the
one they are processed in kernel space, e.g interrupts disabled.

For knowing something more about it have a look at the README in
"base/usi" (USI stand for user space interrupts).

Paolo

On 06/18/2018 10:36 AM, Guo Yunfei wrote:
> And , I even enable the option of:
> Disable immediate rescheduling from within ISRs
>
> according to your mailing list thread of
> http://mail.rtai.org/pipermail/rtai/2015-January/026651.html
>
> but still low efficiency in my IPC mechanism.
>
> On Mon, Jun 18, 2018 at 4:59 AM, Paolo Mantegazza
> <***@polimi.it <mailto:***@polimi.it>> wrote:
>
> As a further comment, I would say that, seeing a worst case
> latency of 17 us for an RTAI real time task waiting for a
> semaphore, very likely signalling from within the Linux
> environment, is a quite good result.
>
> Moreover take into account that you are measuring not only you isr
> processing time but a whole double task switching. The second one
> being, likely again, a Linux task wake up.
>
> Paolo.
>
> ________________________________________
> From: Paolo Mantegazza
> Sent: Sunday, June 17, 2018 10:37 PM
> To: Guo Yunfei; ***@rtai.org <mailto:***@rtai.org>
> Subject: RE: [Rtai] (no subject)
>
> ????? rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device",
> dev); ?????
> You are trying to menage a Linux interrupt using an RTAI hard real
> time task.
> No surprise of a reduced efficiency. If you want to carry out real
> time interrupt handling in user space try rtai_usi.
> The whole stuff will be crried otu in user space.
>
> Nonetheless, if you want to have a kernel handler, waking an RTAI
> hard real time task in user space, register a native RTAI handler.
>
> Paolo
>
> ________________________________________
> From: Rtai [rtai-***@rtai.org <mailto:rtai-***@rtai.org>]
> on behalf of Guo Yunfei [***@gmail.com
> <mailto:***@gmail.com>]
> Sent: Sunday, June 17, 2018 10:11 AM
> To: ***@rtai.org <mailto:***@rtai.org>
> Subject: [Rtai] (no subject)
>
> Hi, everyone:
>
> I'm face the problem of rt_sem_signal() low efficiency.
>
> I register my PCI interrupt handler by:
> rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev);
>
> the interrupt handler code is:
>
> static irqreturn_t my_isr(int irq, void *data)
> {
>     struct my_device *dev = data;
>
>     unsigned short LINTSR;    //LINTSR:local interrupt status
> register;
>     int iIntSource = 0;
>     LINTSR = readw(dev->caddr +0x28); // read pci card interrupt
> status
>
>     if (LINTSR & 0x1)    {
>         iIntSource = ReadIntSource(); //check the interrupt source.
>         if((iIntSource & 0x1) == 0x1)        {
>             ClearInterruptFunc();
>             shm_ptr->IntType = 1;//Flag_ISR;
>         }
>
>         volatile RTIME t1, t2, t_elapsed;  //check the
> rt_sem_signal() elapse time
>         t1 = rt_get_cpu_time_ns();
>         rt_sem_signal(&sem);
>         t2 = rt_get_cpu_time_ns();
>         t_elapsed = (t2 - t1);
>
>         //printk(" %d \n",t_elapsed);
>         writew(LINTSR | 0xF,dev->caddr+0x28);   //clear interrupt ;
>     }
>     return IRQ_HANDLED;
> }
>
> Then, I implement the real isr work in user space LXRT method like
> below, for I want enjoy the convinience of user space driver
> developing.
>
> static int Answer_irq()
> {
>     if (!(irqtask = rt_thread_init(nam2num("ANSWERIRQTSK"), 0, 0,
> SCHED_FIFO, 0x0)))    {
>         printf("CANNOT INIT PROCESS ANSWERIRQTSK\n");
>         exit(1);
>     }
>     mlockall(MCL_CURRENT | MCL_FUTURE);
>
>     rt_make_hard_real_time();
>     while (1)    {
>         rt_sem_wait(sem);
>         switch (shm_ptr->IntType)
>         {
>         case 1:
>             REAL_ISR(); //the real isr working here.
>             break;
>             return 0;
>         }
>     }
>     rt_make_soft_real_time();
>     rt_task_delete(irqtask);
>     return 0;
> }
>
> This mechanism can working smooth, but,its efficiency is much lower.
> around 33% slower than that directly runing the REAL_ISR()  in
> kernel space interrupt handler(codes as below)
>
> static irqreturn_t my_isr(int irq, void *data)
> {
>     struct my_device *dev = data;
>
>     unsigned short LINTSR;    //LINTSR:local interrupt status
> register;
>     int iIntSource = 0;
>     LINTSR = readw(dev->caddr +0x28); // read pci card interrupt
> status
>
>     if (LINTSR & 0x1)        {
>         iIntSource = ReadIntSource(); //check the interrupt source.
>         if((iIntSource & 0x1) == 0x1)        {
>             clearInterruptFunc();
>             REAL_ISR();      // real isr working in interrupt handler
>         }
>
>         writew(LINTSR | 0xF,dev->caddr+0x28);   //clear interrupt ;
>     }
>     return IRQ_HANDLED;
> }
>
> So, I suspect rt_sem_signal(&sem) give much delay in this mechanism.
> my rt_sem_signal(&sem) elapse time dmesg segment like below:
> [  198.234668]  1738
> [  198.235488]  4988
> [  198.236308]  913
> [  198.237128]  8038
> [  198.237945]  1625
> [  198.238764]  5038
> [  198.239584]  912
> [  198.240404]  3750
> [  198.241222]  1575
> [  198.242042]  5275
> [  198.242866]  2025
> [  198.243690]  11976
> [  198.244498]  1662
> [  198.245317]  5125
> [  198.246137]  875
> [  198.246959]  8201
> [  198.247774]  1612
> [  198.248593]  8351
> [  198.249413]  725
> [  198.250234]  7714
> [  198.251051]  1625
> [  198.251871]  5125
> [  198.252691]  1350
> [  198.253513]  8087
> [  198.254329]  1775
> [  198.255147]  8662
> [  198.255966]  813
> [  198.256787]  7387
> [  198.257604]  1525
> [  198.258429]  4725
> [  198.259266]  15699
> [  198.260064]  5362
> [  198.260882]  1562
> [  198.261707]  4975
> [  198.262540]  15750
> [  198.263346]  6388
> [  198.264160]  2063
> [  198.264987]  2337
> [  198.265822]  16974
> [  198.266625]  6350
> [  198.267442]  2475
> [  198.268268]  2350
> [  198.269084]  11675
>
> Is this normal?  (My platform is Intel® Celeron N3160,1.6 GHz
> (Quad-Core)).
> Or, any suggestion for my problem to raise its IPC efficiency?
>
>
> Thanks in advance.
>
> Guo Yunfei
>
>
>
>
>
>
>
>
>
Guo Yunfei
2018-06-24 15:30:12 UTC
Permalink
Dear Paolo:

As follow your suggestion, I made a new mechanism similar to the
showroom/user/i386/usi/usi_tasklet.c.
Now all codes write in user space, this feels very good. thank you.
It can working smooth. (codes belowed).
But ,the isr() runing still in low frequency, not as fast as it in kernel
space.
almost slower 50% than it in kernel space.

static void my_handler(unsigned long data)

{

static int first;

if (!first) {

first = 1;

rtai_cli();

}


do {

iIntSource = ReadIntSource(); // read the interrupt
register status here

if((iIntSource & 0x1) == 0x1) {// check if it is the
correct interrupt source

iIsrCount1++;

Unlatch(); //unlatch the interrupt line

ISR();

}

//clear interrupt here;

} while(0);


rt_enable_irq( my_IRQ );

}


int Hardware_Open(int val1, int val2)

{

if (!(maint = rt_task_init(nam2num("MAIN"), 0, 0, 0))) {

printf("CANNOT INIT MAIN TASK > MAIN <\n");

exit(1);

}


tasklet = rt_init_tasklet();

mlockall(MCL_CURRENT | MCL_FUTURE);


rt_insert_tasklet(tasklet, 0, my_handler, 888, nam2num("TSKLET"), 1);

rt_request_irq_task(my_IRQ, tasklet, RT_IRQ_TASKLET, 1);


rt_enable_irq(my_IRQ);


return 0;

}



Are there something special need I pay attentione to it?

Thank you very much.

Best Regards
Guo Yunfei

On Mon, Jun 18, 2018 at 5:31 PM, Paolo Mantegazza <
***@polimi.it> wrote:

> Disabling immediate rescheduling is not what you should do. It lock the
> scheduler till you exited all real time interrupts have been processed. If
> you are sure to have completed processing your interaction with your device
> you should enable it.
>
> Take into account that the way you have tested it is nothing but another
> kind of latency test.
> Therefore you are getting the very same figures of any similar test.
> Moreover, because you cannot be sure that your executions are exactly the
> same at different times, nothing can be said by looking at you results.
>
> That said RTAI has its structured way to develop user space interrupt
> handlers. It is not much dissimilar from yours, but does not require
> anything in kernel space and can provide the closest environment to the one
> they are processed in kernel space, e.g interrupts disabled.
>
> For knowing something more about it have a look at the README in
> "base/usi" (USI stand for user space interrupts).
>
> Paolo
>
>
> On 06/18/2018 10:36 AM, Guo Yunfei wrote:
>
> And , I even enable the option of:
> Disable immediate rescheduling from within ISRs
>
> according to your mailing list thread of
> http://mail.rtai.org/pipermail/rtai/2015-January/026651.html
>
> but still low efficiency in my IPC mechanism.
>
> On Mon, Jun 18, 2018 at 4:59 AM, Paolo Mantegazza <
> ***@polimi.it> wrote:
>
>> As a further comment, I would say that, seeing a worst case latency of 17
>> us for an RTAI real time task waiting for a semaphore, very likely
>> signalling from within the Linux environment, is a quite good result.
>>
>> Moreover take into account that you are measuring not only you isr
>> processing time but a whole double task switching. The second one being,
>> likely again, a Linux task wake up.
>>
>> Paolo.
>>
>> ________________________________________
>> From: Paolo Mantegazza
>> Sent: Sunday, June 17, 2018 10:37 PM
>> To: Guo Yunfei; ***@rtai.org
>> Subject: RE: [Rtai] (no subject)
>>
>> ????? rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev);
>> ?????
>> You are trying to menage a Linux interrupt using an RTAI hard real time
>> task.
>> No surprise of a reduced efficiency. If you want to carry out real time
>> interrupt handling in user space try rtai_usi.
>> The whole stuff will be crried otu in user space.
>>
>> Nonetheless, if you want to have a kernel handler, waking an RTAI hard
>> real time task in user space, register a native RTAI handler.
>>
>> Paolo
>>
>> ________________________________________
>> From: Rtai [rtai-***@rtai.org] on behalf of Guo Yunfei [
>> ***@gmail.com]
>> Sent: Sunday, June 17, 2018 10:11 AM
>> To: ***@rtai.org
>> Subject: [Rtai] (no subject)
>>
>> Hi, everyone:
>>
>> I'm face the problem of rt_sem_signal() low efficiency.
>>
>> I register my PCI interrupt handler by:
>> rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev);
>>
>> the interrupt handler code is:
>>
>> static irqreturn_t my_isr(int irq, void *data)
>> {
>> struct my_device *dev = data;
>>
>> unsigned short LINTSR; //LINTSR:local interrupt status register;
>> int iIntSource = 0;
>> LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status
>>
>> if (LINTSR & 0x1) {
>> iIntSource = ReadIntSource(); //check the interrupt source.
>> if((iIntSource & 0x1) == 0x1) {
>> ClearInterruptFunc();
>> shm_ptr->IntType = 1;//Flag_ISR;
>> }
>>
>> volatile RTIME t1, t2, t_elapsed; //check the rt_sem_signal()
>> elapse time
>> t1 = rt_get_cpu_time_ns();
>> rt_sem_signal(&sem);
>> t2 = rt_get_cpu_time_ns();
>> t_elapsed = (t2 - t1);
>>
>> //printk(" %d \n",t_elapsed);
>> writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt ;
>> }
>> return IRQ_HANDLED;
>> }
>>
>> Then, I implement the real isr work in user space LXRT method like below,
>> for I want enjoy the convinience of user space driver developing.
>>
>> static int Answer_irq()
>> {
>> if (!(irqtask = rt_thread_init(nam2num("ANSWERIRQTSK"), 0, 0,
>> SCHED_FIFO, 0x0))) {
>> printf("CANNOT INIT PROCESS ANSWERIRQTSK\n");
>> exit(1);
>> }
>> mlockall(MCL_CURRENT | MCL_FUTURE);
>>
>> rt_make_hard_real_time();
>> while (1) {
>> rt_sem_wait(sem);
>> switch (shm_ptr->IntType)
>> {
>> case 1:
>> REAL_ISR(); //the real isr working here.
>> break;
>> return 0;
>> }
>> }
>> rt_make_soft_real_time();
>> rt_task_delete(irqtask);
>> return 0;
>> }
>>
>> This mechanism can working smooth, but,its efficiency is much lower.
>> around 33% slower than that directly runing the REAL_ISR() in kernel
>> space interrupt handler(codes as below)
>>
>> static irqreturn_t my_isr(int irq, void *data)
>> {
>> struct my_device *dev = data;
>>
>> unsigned short LINTSR; //LINTSR:local interrupt status register;
>> int iIntSource = 0;
>> LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status
>>
>> if (LINTSR & 0x1) {
>> iIntSource = ReadIntSource(); //check the interrupt source.
>> if((iIntSource & 0x1) == 0x1) {
>> clearInterruptFunc();
>> REAL_ISR(); // real isr working in interrupt handler
>> }
>>
>> writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt ;
>> }
>> return IRQ_HANDLED;
>> }
>>
>> So, I suspect rt_sem_signal(&sem) give much delay in this mechanism.
>> my rt_sem_signal(&sem) elapse time dmesg segment like below:
>> [ 198.234668] 1738
>> [ 198.235488] 4988
>> [ 198.236308] 913
>> [ 198.237128] 8038
>> [ 198.237945] 1625
>> [ 198.238764] 5038
>> [ 198.239584] 912
>> [ 198.240404] 3750
>> [ 198.241222] 1575
>> [ 198.242042] 5275
>> [ 198.242866] 2025
>> [ 198.243690] 11976
>> [ 198.244498] 1662
>> [ 198.245317] 5125
>> [ 198.246137] 875
>> [ 198.246959] 8201
>> [ 198.247774] 1612
>> [ 198.248593] 8351
>> [ 198.249413] 725
>> [ 198.250234] 7714
>> [ 198.251051] 1625
>> [ 198.251871] 5125
>> [ 198.252691] 1350
>> [ 198.253513] 8087
>> [ 198.254329] 1775
>> [ 198.255147] 8662
>> [ 198.255966] 813
>> [ 198.256787] 7387
>> [ 198.257604] 1525
>> [ 198.258429] 4725
>> [ 198.259266] 15699
>> [ 198.260064] 5362
>> [ 198.260882] 1562
>> [ 198.261707] 4975
>> [ 198.262540] 15750
>> [ 198.263346] 6388
>> [ 198.264160] 2063
>> [ 198.264987] 2337
>> [ 198.265822] 16974
>> [ 198.266625] 6350
>> [ 198.267442] 2475
>> [ 198.268268] 2350
>> [ 198.269084] 11675
>>
>> Is this normal? (My platform is Intel® Celeron N3160,1.6 GHz
>> (Quad-Core)).
>> Or, any suggestion for my problem to raise its IPC efficiency?
>>
>>
>> Thanks in advance.
>>
>> Guo Yunfei
>>
>>
>>
>>
>>
>>
>>
>>
>>
>
>
Paolo Mantegazza
2018-06-25 07:43:23 UTC
Permalink
Without knowing your application I have no precise clue. A suggestion I
can give is to try the other approach, i.e. using a task process instead
of a tasklet. It is much as your original version and avoid a double
context switching, due to tasklet being managed by a supervisor task. In
showroom there is a related example. Moreover try enabling the immediate
rescheduling in interrupts.

Recall that a user space interrupt handler may be simple to develop
Nonetheless is subjected to larger latencies and jitter.

Paolo


On 06/24/2018 05:30 PM, Guo Yunfei wrote:
> Dear Paolo:
>
> As follow your suggestion, I made a new mechanism similar to the
> showroom/user/i386/usi/usi_tasklet.c.
> Now all codes write in user space, this feels very good. thank you.
>  It can working smooth. (codes belowed).
> But ,the isr() runing still in low frequency, not as fast as it in
> kernel space.
> almost slower 50% than it in kernel space.
>
> staticvoidmy_handler(unsignedlongdata)
> {
> staticintfirst;
> if(!first){
> first=1;
> rtai_cli();
> }
> do{
> iIntSource=ReadIntSource(); //readtheinterruptregisterstatushere
> if((iIntSource&0x1)==0x1){//checkifitisthecorrectinterruptsource
> iIsrCount1++;
> Unlatch();//unlatchtheinterruptline
> ISR();
> }
> //clearinterrupthere;
> }while(0);
> rt_enable_irq(my_IRQ);
> }
> intHardware_Open(int val1,intval2)
> {
> if(!(maint=rt_task_init(nam2num("MAIN"),0,0,0))){
> printf("CANNOTINITMAINTASK>MAIN<\n");
> exit(1);
> }
> tasklet=rt_init_tasklet();
> mlockall(MCL_CURRENT|MCL_FUTURE);
> rt_insert_tasklet(tasklet,0,my_handler,888,nam2num("TSKLET"),1);
> rt_request_irq_task(my_IRQ,tasklet,RT_IRQ_TASKLET,1);
> rt_enable_irq(my_IRQ);
> return0;
> }
>
> Are there something special need I pay attentione to it?
>
> Thank you very much.
>
> Best Regards
> Guo Yunfei
>
> On Mon, Jun 18, 2018 at 5:31 PM, Paolo Mantegazza
> <***@polimi.it <mailto:***@polimi.it>> wrote:
>
> Disabling immediate rescheduling is not what you should do. It
> lock the scheduler till you exited all real time interrupts have
> been processed. If you are sure to have completed processing your
> interaction with your device you should enable it.
>
> Take into account that the way you have tested it is nothing but
> another kind of latency test.
> Therefore you are getting the very same figures of any similar test.
> Moreover, because you cannot be sure that your executions are
> exactly the same at different times, nothing can be said by
> looking at you results.
>
> That said RTAI has its structured way to develop user space
> interrupt handlers. It is not much dissimilar from yours, but does
> not require anything in kernel space and can provide the closest
> environment to the one they are processed in kernel space, e.g
> interrupts disabled.
>
> For knowing something more about it have a look at the README in
> "base/usi" (USI stand for user space interrupts).
>
> Paolo
>
>
> On 06/18/2018 10:36 AM, Guo Yunfei wrote:
>> And , I even enable the option of:
>> Disable immediate rescheduling from within ISRs
>>
>> according to your mailing list thread of
>> http://mail.rtai.org/pipermail/rtai/2015-January/026651.html
>> <http://mail.rtai.org/pipermail/rtai/2015-January/026651.html>
>>
>> but still low efficiency in my IPC mechanism.
>>
>> On Mon, Jun 18, 2018 at 4:59 AM, Paolo Mantegazza
>> <***@polimi.it <mailto:***@polimi.it>>
>> wrote:
>>
>> As a further comment, I would say that, seeing a worst case
>> latency of 17 us for an RTAI real time task waiting for a
>> semaphore, very likely signalling from within the Linux
>> environment, is a quite good result.
>>
>> Moreover take into account that you are measuring not only
>> you isr processing time but a whole double task switching.
>> The second one being, likely again, a Linux task wake up.
>>
>> Paolo.
>>
>> ________________________________________
>> From: Paolo Mantegazza
>> Sent: Sunday, June 17, 2018 10:37 PM
>> To: Guo Yunfei; ***@rtai.org <mailto:***@rtai.org>
>> Subject: RE: [Rtai] (no subject)
>>
>> ????? rt_request_linux_irq(pdev->irq, my_isr,
>> "my_pci_device", dev); ?????
>> You are trying to menage a Linux interrupt using an RTAI hard
>> real time task.
>> No surprise of a reduced efficiency. If you want to carry out
>> real time interrupt handling in user space try rtai_usi.
>> The whole stuff will be crried otu in user space.
>>
>> Nonetheless, if you want to have a kernel handler, waking an
>> RTAI hard real time task in user space, register a native
>> RTAI handler.
>>
>> Paolo
>>
>> ________________________________________
>> From: Rtai [rtai-***@rtai.org
>> <mailto:rtai-***@rtai.org>] on behalf of Guo Yunfei
>> [***@gmail.com <mailto:***@gmail.com>]
>> Sent: Sunday, June 17, 2018 10:11 AM
>> To: ***@rtai.org <mailto:***@rtai.org>
>> Subject: [Rtai] (no subject)
>>
>> Hi, everyone:
>>
>> I'm face the problem of rt_sem_signal() low efficiency.
>>
>> I register my PCI interrupt handler by:
>> rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev);
>>
>> the interrupt handler code is:
>>
>> static irqreturn_t my_isr(int irq, void *data)
>> {
>>     struct my_device *dev = data;
>>
>>     unsigned short LINTSR; //LINTSR:local interrupt status
>> register;
>>     int iIntSource = 0;
>>     LINTSR = readw(dev->caddr +0x28); // read pci card
>> interrupt status
>>
>>     if (LINTSR & 0x1)    {
>>         iIntSource = ReadIntSource(); //check the interrupt
>> source.
>>         if((iIntSource & 0x1) == 0x1)       {
>>             ClearInterruptFunc();
>>             shm_ptr->IntType = 1;//Flag_ISR;
>>         }
>>
>>         volatile RTIME t1, t2, t_elapsed; //check the
>> rt_sem_signal() elapse time
>>         t1 = rt_get_cpu_time_ns();
>>         rt_sem_signal(&sem);
>>         t2 = rt_get_cpu_time_ns();
>>         t_elapsed = (t2 - t1);
>>
>>         //printk(" %d \n",t_elapsed);
>>         writew(LINTSR | 0xF,dev->caddr+0x28);         
>> //clear interrupt ;
>>     }
>>     return IRQ_HANDLED;
>> }
>>
>> Then, I implement the real isr work in user space LXRT method
>> like below, for I want enjoy the convinience of user space
>> driver developing.
>>
>> static int Answer_irq()
>> {
>>     if (!(irqtask = rt_thread_init(nam2num("ANSWERIRQTSK"),
>> 0, 0, SCHED_FIFO, 0x0)))    {
>>         printf("CANNOT INIT PROCESS ANSWERIRQTSK\n");
>>         exit(1);
>>     }
>>     mlockall(MCL_CURRENT | MCL_FUTURE);
>>
>>     rt_make_hard_real_time();
>>     while (1)    {
>>         rt_sem_wait(sem);
>>         switch (shm_ptr->IntType)
>>         {
>>         case 1:
>>             REAL_ISR(); //the real isr working here.
>>             break;
>>             return 0;
>>         }
>>     }
>>     rt_make_soft_real_time();
>>     rt_task_delete(irqtask);
>>     return 0;
>> }
>>
>> This mechanism can working smooth, but,its efficiency is much
>> lower.
>> around 33% slower than that directly runing the REAL_ISR() 
>> in kernel space interrupt handler(codes as below)
>>
>> static irqreturn_t my_isr(int irq, void *data)
>> {
>>     struct my_device *dev = data;
>>
>>     unsigned short LINTSR; //LINTSR:local interrupt status
>> register;
>>     int iIntSource = 0;
>>     LINTSR = readw(dev->caddr +0x28); // read pci card
>> interrupt status
>>
>>     if (LINTSR & 0x1)        {
>>         iIntSource = ReadIntSource(); //check the interrupt
>> source.
>>         if((iIntSource & 0x1) == 0x1)       {
>>             clearInterruptFunc();
>>             REAL_ISR();      // real isr working in interrupt
>> handler
>>         }
>>
>>         writew(LINTSR | 0xF,dev->caddr+0x28);         
>> //clear interrupt ;
>>     }
>>     return IRQ_HANDLED;
>> }
>>
>> So, I suspect rt_sem_signal(&sem) give much delay in this
>> mechanism.
>> my rt_sem_signal(&sem) elapse time dmesg segment like below:
>> [  198.234668]  1738
>> [  198.235488]  4988
>> [  198.236308]  913
>> [  198.237128]  8038
>> [  198.237945]  1625
>> [  198.238764]  5038
>> [  198.239584]  912
>> [  198.240404]  3750
>> [  198.241222]  1575
>> [  198.242042]  5275
>> [  198.242866]  2025
>> [  198.243690]  11976
>> [  198.244498]  1662
>> [  198.245317]  5125
>> [  198.246137]  875
>> [  198.246959]  8201
>> [  198.247774]  1612
>> [  198.248593]  8351
>> [  198.249413]  725
>> [  198.250234]  7714
>> [  198.251051]  1625
>> [  198.251871]  5125
>> [  198.252691]  1350
>> [  198.253513]  8087
>> [  198.254329]  1775
>> [  198.255147]  8662
>> [  198.255966]  813
>> [  198.256787]  7387
>> [  198.257604]  1525
>> [  198.258429]  4725
>> [  198.259266]  15699
>> [  198.260064]  5362
>> [  198.260882]  1562
>> [  198.261707]  4975
>> [  198.262540]  15750
>> [  198.263346]  6388
>> [  198.264160]  2063
>> [  198.264987]  2337
>> [  198.265822]  16974
>> [  198.266625]  6350
>> [  198.267442]  2475
>> [  198.268268]  2350
>> [  198.269084]  11675
>>
>> Is this normal?  (My platform is Intel® Celeron N3160,1.6 GHz
>> (Quad-Core)).
>> Or, any suggestion for my problem to raise its IPC efficiency?
>>
>>
>> Thanks in advance.
>>
>> Guo Yunfei
>>
>>
>>
>>
>>
>>
>>
>>
>>
>
>
Guo Yunfei
2018-06-25 22:37:53 UTC
Permalink
Dear Paolo:

I fix the problem by modified some parameters in my algorithm, finally.
The rtai is good.
I like it.

thank you again.

Best Regards
Guo Yunfei


On Mon, Jun 25, 2018 at 3:43 PM, Paolo Mantegazza <
***@polimi.it> wrote:

> Without knowing your application I have no precise clue. A suggestion I
> can give is to try the other approach, i.e. using a task process instead of
> a tasklet. It is much as your original version and avoid a double context
> switching, due to tasklet being managed by a supervisor task. In showroom
> there is a related example. Moreover try enabling the immediate
> rescheduling in interrupts.
>
> Recall that a user space interrupt handler may be simple to develop
> Nonetheless is subjected to larger latencies and jitter.
>
> Paolo
>
>
>
> On 06/24/2018 05:30 PM, Guo Yunfei wrote:
>
> Dear Paolo:
>
> As follow your suggestion, I made a new mechanism similar to the
> showroom/user/i386/usi/usi_tasklet.c.
> Now all codes write in user space, this feels very good. thank you.
> It can working smooth. (codes belowed).
> But ,the isr() runing still in low frequency, not as fast as it in kernel
> space.
> almost slower 50% than it in kernel space.
>
> static void my_handler(unsigned long data)
>
> {
>
> static int first;
>
> if (!first) {
>
> first = 1;
>
> rtai_cli();
>
> }
>
> do {
>
> iIntSource = ReadIntSource(); // read the interrupt register status here
>
> if((iIntSource & 0x1) == 0x1) {// check if it is the correct interrupt source
>
> iIsrCount1++;
>
> Unlatch(); //unlatch the interrupt line
>
> ISR();
>
> }
>
> //clear interrupt here;
>
> } while(0);
>
> rt_enable_irq( my_IRQ );
>
> }
>
> int Hardware_Open(int val1, int val2)
>
> {
>
> if (!(maint = rt_task_init(nam2num("MAIN"), 0, 0, 0))) {
>
> printf("CANNOT INIT MAIN TASK > MAIN <\n");
>
> exit(1);
>
> }
>
> tasklet = rt_init_tasklet();
>
> mlockall(MCL_CURRENT | MCL_FUTURE);
>
> rt_insert_tasklet(tasklet, 0, my_handler, 888, nam2num("TSKLET"), 1);
>
> rt_request_irq_task(my_IRQ, tasklet, RT_IRQ_TASKLET, 1);
>
> rt_enable_irq(my_IRQ);
>
> return 0;
>
> }
>
>
> Are there something special need I pay attentione to it?
>
> Thank you very much.
>
> Best Regards
> Guo Yunfei
>
> On Mon, Jun 18, 2018 at 5:31 PM, Paolo Mantegazza <
> ***@polimi.it> wrote:
>
>> Disabling immediate rescheduling is not what you should do. It lock the
>> scheduler till you exited all real time interrupts have been processed. If
>> you are sure to have completed processing your interaction with your device
>> you should enable it.
>>
>> Take into account that the way you have tested it is nothing but another
>> kind of latency test.
>> Therefore you are getting the very same figures of any similar test.
>> Moreover, because you cannot be sure that your executions are exactly the
>> same at different times, nothing can be said by looking at you results.
>>
>> That said RTAI has its structured way to develop user space interrupt
>> handlers. It is not much dissimilar from yours, but does not require
>> anything in kernel space and can provide the closest environment to the one
>> they are processed in kernel space, e.g interrupts disabled.
>>
>> For knowing something more about it have a look at the README in
>> "base/usi" (USI stand for user space interrupts).
>>
>> Paolo
>>
>>
>> On 06/18/2018 10:36 AM, Guo Yunfei wrote:
>>
>> And , I even enable the option of:
>> Disable immediate rescheduling from within ISRs
>>
>> according to your mailing list thread of
>> http://mail.rtai.org/pipermail/rtai/2015-January/026651.html
>>
>> but still low efficiency in my IPC mechanism.
>>
>> On Mon, Jun 18, 2018 at 4:59 AM, Paolo Mantegazza <
>> ***@polimi.it> wrote:
>>
>>> As a further comment, I would say that, seeing a worst case latency of
>>> 17 us for an RTAI real time task waiting for a semaphore, very likely
>>> signalling from within the Linux environment, is a quite good result.
>>>
>>> Moreover take into account that you are measuring not only you isr
>>> processing time but a whole double task switching. The second one being,
>>> likely again, a Linux task wake up.
>>>
>>> Paolo.
>>>
>>> ________________________________________
>>> From: Paolo Mantegazza
>>> Sent: Sunday, June 17, 2018 10:37 PM
>>> To: Guo Yunfei; ***@rtai.org
>>> Subject: RE: [Rtai] (no subject)
>>>
>>> ????? rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev);
>>> ?????
>>> You are trying to menage a Linux interrupt using an RTAI hard real time
>>> task.
>>> No surprise of a reduced efficiency. If you want to carry out real time
>>> interrupt handling in user space try rtai_usi.
>>> The whole stuff will be crried otu in user space.
>>>
>>> Nonetheless, if you want to have a kernel handler, waking an RTAI hard
>>> real time task in user space, register a native RTAI handler.
>>>
>>> Paolo
>>>
>>> ________________________________________
>>> From: Rtai [rtai-***@rtai.org] on behalf of Guo Yunfei [
>>> ***@gmail.com]
>>> Sent: Sunday, June 17, 2018 10:11 AM
>>> To: ***@rtai.org
>>> Subject: [Rtai] (no subject)
>>>
>>> Hi, everyone:
>>>
>>> I'm face the problem of rt_sem_signal() low efficiency.
>>>
>>> I register my PCI interrupt handler by:
>>> rt_request_linux_irq(pdev->irq, my_isr, "my_pci_device", dev);
>>>
>>> the interrupt handler code is:
>>>
>>> static irqreturn_t my_isr(int irq, void *data)
>>> {
>>> struct my_device *dev = data;
>>>
>>> unsigned short LINTSR; //LINTSR:local interrupt status register;
>>> int iIntSource = 0;
>>> LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status
>>>
>>> if (LINTSR & 0x1) {
>>> iIntSource = ReadIntSource(); //check the interrupt source.
>>> if((iIntSource & 0x1) == 0x1) {
>>> ClearInterruptFunc();
>>> shm_ptr->IntType = 1;//Flag_ISR;
>>> }
>>>
>>> volatile RTIME t1, t2, t_elapsed; //check the rt_sem_signal()
>>> elapse time
>>> t1 = rt_get_cpu_time_ns();
>>> rt_sem_signal(&sem);
>>> t2 = rt_get_cpu_time_ns();
>>> t_elapsed = (t2 - t1);
>>>
>>> //printk(" %d \n",t_elapsed);
>>> writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt
>>> ;
>>> }
>>> return IRQ_HANDLED;
>>> }
>>>
>>> Then, I implement the real isr work in user space LXRT method like
>>> below, for I want enjoy the convinience of user space driver developing.
>>>
>>> static int Answer_irq()
>>> {
>>> if (!(irqtask = rt_thread_init(nam2num("ANSWERIRQTSK"), 0, 0,
>>> SCHED_FIFO, 0x0))) {
>>> printf("CANNOT INIT PROCESS ANSWERIRQTSK\n");
>>> exit(1);
>>> }
>>> mlockall(MCL_CURRENT | MCL_FUTURE);
>>>
>>> rt_make_hard_real_time();
>>> while (1) {
>>> rt_sem_wait(sem);
>>> switch (shm_ptr->IntType)
>>> {
>>> case 1:
>>> REAL_ISR(); //the real isr working here.
>>> break;
>>> return 0;
>>> }
>>> }
>>> rt_make_soft_real_time();
>>> rt_task_delete(irqtask);
>>> return 0;
>>> }
>>>
>>> This mechanism can working smooth, but,its efficiency is much lower.
>>> around 33% slower than that directly runing the REAL_ISR() in kernel
>>> space interrupt handler(codes as below)
>>>
>>> static irqreturn_t my_isr(int irq, void *data)
>>> {
>>> struct my_device *dev = data;
>>>
>>> unsigned short LINTSR; //LINTSR:local interrupt status register;
>>> int iIntSource = 0;
>>> LINTSR = readw(dev->caddr +0x28); // read pci card interrupt status
>>>
>>> if (LINTSR & 0x1) {
>>> iIntSource = ReadIntSource(); //check the interrupt source.
>>> if((iIntSource & 0x1) == 0x1) {
>>> clearInterruptFunc();
>>> REAL_ISR(); // real isr working in interrupt handler
>>> }
>>>
>>> writew(LINTSR | 0xF,dev->caddr+0x28); //clear interrupt
>>> ;
>>> }
>>> return IRQ_HANDLED;
>>> }
>>>
>>> So, I suspect rt_sem_signal(&sem) give much delay in this mechanism.
>>> my rt_sem_signal(&sem) elapse time dmesg segment like below:
>>> [ 198.234668] 1738
>>> [ 198.235488] 4988
>>> [ 198.236308] 913
>>> [ 198.237128] 8038
>>> [ 198.237945] 1625
>>> [ 198.238764] 5038
>>> [ 198.239584] 912
>>> [ 198.240404] 3750
>>> [ 198.241222] 1575
>>> [ 198.242042] 5275
>>> [ 198.242866] 2025
>>> [ 198.243690] 11976
>>> [ 198.244498] 1662
>>> [ 198.245317] 5125
>>> [ 198.246137] 875
>>> [ 198.246959] 8201
>>> [ 198.247774] 1612
>>> [ 198.248593] 8351
>>> [ 198.249413] 725
>>> [ 198.250234] 7714
>>> [ 198.251051] 1625
>>> [ 198.251871] 5125
>>> [ 198.252691] 1350
>>> [ 198.253513] 8087
>>> [ 198.254329] 1775
>>> [ 198.255147] 8662
>>> [ 198.255966] 813
>>> [ 198.256787] 7387
>>> [ 198.257604] 1525
>>> [ 198.258429] 4725
>>> [ 198.259266] 15699
>>> [ 198.260064] 5362
>>> [ 198.260882] 1562
>>> [ 198.261707] 4975
>>> [ 198.262540] 15750
>>> [ 198.263346] 6388
>>> [ 198.264160] 2063
>>> [ 198.264987] 2337
>>> [ 198.265822] 16974
>>> [ 198.266625] 6350
>>> [ 198.267442] 2475
>>> [ 198.268268] 2350
>>> [ 198.269084] 11675
>>>
>>> Is this normal? (My platform is Intel® Celeron N3160,1.6 GHz
>>> (Quad-Core)).
>>> Or, any suggestion for my problem to raise its IPC efficiency?
>>>
>>>
>>> Thanks in advance.
>>>
>>> Guo Yunfei
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>
>>
>
>
Loading...