From mboxrd@z Thu Jan 1 00:00:00 1970 Message-Id: Date: Thu, 19 Apr 2007 11:49:06 +0200 From: "Nicolas BLANCHARD" Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="=__Part30175C02.0__=" Subject: [Xenomai-help] [RTDM] IRQ lock problem ? List-Id: Help regarding installation and common use of Xenomai List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: xenomai-help, xenomai@xenomai.org, --=__Part30175C02.0__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Hi, I've write an rtdm driver and i have a problem. I use ioctl (rt_dev_ioctl) to read and write data (RTC time) on cmos. (I know it could better to use _rt_dev_read or rt_dev_write but it was my first rtdm driver, and i' think that it's not the cause of my problem). My user application (Native xenomai task) use this rt_dev_ioctl each 100 ms to read data on cmos. But, sometime (each 3 or 4 days), i read bad values. this is the code to read the cmos (call in an rt_dev_ioctl) : //--------------------------------------------------------------------------------------------- static unsigned char get_cmos_time(struct rtc146818drv_context *ctx, struct rtc_time *rtc_tm) { unsigned char uip; rtdm_lockctx_t lock_ctx; rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); if(uip == 0) { rtc_tm->tm_year = CMOS_READ(RTC_YEAR); rtc_tm->tm_mon = CMOS_READ(RTC_MONTH); rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); rtc_tm->tm_wday = CMOS_READ(RTC_DAY_OF_WEEK); } rtc_tm->tm_yday = 0; rtc_tm->tm_isdst = 0; rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); return uip; } //--------------------------------------------------------------------------------------------- Data are read on MC146818A chipset, documentaton of this chipset explain that an update cycle is execute once per second and during this update RTC_values or not fully available. So, we test the uip,when uip==0 the update cycle is not in progress and will not be for at least 244 us (for all time bases). So to be sure that in thoses 244 us i've time to execute my code, i've disable the premption with rtdm_lock_get_irqsave. But sometime, like if the update cycle begin in the midle of my code, i read bad value (value 165 exactly). For example i read this bad time : "19/04/07 11:165:165 day 165" (like if i've been prempt after CMOS_READ(RTC_HOURS) instructions). or "19//04/165 165:165:165 day 165" (like if i've been prempt after CMOS_READ(RTC_MONTH) instructions). We use the same hardware with other system (RTLinux), with same test on uip bit and we have no problem ( problem isn't on the chipset .. ). So Is my rtdm_lock_get_irqsave and restore use correct ? Is it sure that my critical section is protected from any premption with this lock ? i use xenomai 2.3, hal 1.6-03, linux 2.6.19-2. Thanks for your help! --=__Part30175C02.0__= Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Description: HTML
Hi,
 
I've write an rtdm driver and i have a problem.
I use ioctl (rt_dev_ioctl) to read and write data (RTC time) on = cmos.=20
(I know it could better to use _rt_dev_read or rt_dev_write
 but it was my first rtdm driver, and i' think that it's not the = cause=20 of my problem).
 
My user application (Native xenomai task) use this rt_dev_ioctl = each=20 100 ms to read data on cmos.
But, sometime (each 3 or 4 days), i read bad values.
 
this is the code to read the cmos (call in an rt_dev_ioctl) : =
 
//--------------------------------------------------------------------= -------------------------
static unsigned char get_cmos_time(struct rtc146818drv_context=20 *ctx,
           = struct=20 rtc_time *rtc_tm)
{
 unsigned char uip;
 rtdm_lockctx_t&= nbsp;=20 lock_ctx;
 
 rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); 
 
 uip =3D (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
 
 if(uip =3D=3D 0)
 {
     =20= rtc_tm->tm_year =3D CMOS_READ(RTC_YEAR);
   =20   rtc_tm->tm_mon =3D=20 CMOS_READ(RTC_MONTH);
      rtc_tm->tm_mday = =3D=20 CMOS_READ(RTC_DAY_OF_MONTH);
   =20   rtc_tm->tm_hour =3D=20 CMOS_READ(RTC_HOURS);
      rtc_tm->tm_min = =3D=20 CMOS_READ(RTC_MINUTES);
      rtc_tm->tm_sec= =3D=20 CMOS_READ(RTC_SECONDS);
      rtc_tm->tm_wda= y =3D=20 CMOS_READ(RTC_DAY_OF_WEEK);
}
rtc_tm->tm_yday =3D=20 0;
rtc_tm->tm_isdst =3D 0;
rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx);
 
return uip;
}
//--------------------------------------------------------------------= -------------------------
 
Data are read on MC146818A chipset, documentaton of this chipset = explain=20 that an update cycle is execute
once per second and during this update  RTC_values or not = fully=20 available.
So, we test the uip,when uip=3D=3D0 the update cycle is not in = progress and=20 will not be for at least 244 us (for all time bases).
 
So to be sure that in thoses 244 us i've time to execute my code, = i've=20 disable the premption with rtdm_lock_get_irqsave.
But sometime, like if the update cycle begin in the midle of my code, = i=20 read bad value (value 165 exactly).
 
For example i read this bad time :
"19/04/07 11:165:165 day 165" (like if i've been prempt after=20 CMOS_READ(RTC_HOURS) instructions).
or
"19//04/165 165:165:165 day 165" (like if i've been prempt = after=20 CMOS_READ(RTC_MONTH) instructions).
 
We use the same hardware with other system (RTLinux), with same = test=20 on uip bit and we have no problem ( problem isn't on the chipset = ..=20 ).
 
So Is my rtdm_lock_get_irqsave and restore use correct ?
Is it sure that my critical section is protected from any premption = with=20 this lock ?
 
i use xenomai 2.3, hal 1.6-03, linux 2.6.19-2.
 
Thanks for your help!
 
 
 
--=__Part30175C02.0__=-- From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <4627589B.6020909@domain.hid> Date: Thu, 19 Apr 2007 13:55:07 +0200 From: Jan Kiszka MIME-Version: 1.0 References: In-Reply-To: Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enig883458611CDB7CE8E89149FA" Sender: jan.kiszka@domain.hid Subject: Re: [Xenomai-help] [RTDM] IRQ lock problem ? List-Id: Help regarding installation and common use of Xenomai List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Nicolas BLANCHARD Cc: " This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig883458611CDB7CE8E89149FA Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: quoted-printable Nicolas BLANCHARD wrote: > Hi, > =20 > I've write an rtdm driver and i have a problem. > I use ioctl (rt_dev_ioctl) to read and write data (RTC time) on cmos.=20 > (I know it could better to use _rt_dev_read or rt_dev_write=20 > but it was my first rtdm driver, and i' think that it's not the cause > of my problem). > =20 > My user application (Native xenomai task) use this rt_dev_ioctl each > 100 ms to read data on cmos. > But, sometime (each 3 or 4 days), i read bad values. > =20 > this is the code to read the cmos (call in an rt_dev_ioctl) :=20 > =20 > //---------------------------------------------------------------------= ------------------------ > static unsigned char get_cmos_time(struct rtc146818drv_context *ctx, > struct rtc_time *rtc_tm) > { > unsigned char uip; > rtdm_lockctx_t lock_ctx; > =20 > rtdm_lock_get_irqsave(&ctx->lock, lock_ctx);=20 > =20 > uip =3D (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); > =20 > if(uip =3D=3D 0) > { > rtc_tm->tm_year =3D CMOS_READ(RTC_YEAR); > rtc_tm->tm_mon =3D CMOS_READ(RTC_MONTH); > rtc_tm->tm_mday =3D CMOS_READ(RTC_DAY_OF_MONTH); > rtc_tm->tm_hour =3D CMOS_READ(RTC_HOURS); > rtc_tm->tm_min =3D CMOS_READ(RTC_MINUTES); > rtc_tm->tm_sec =3D CMOS_READ(RTC_SECONDS); > rtc_tm->tm_wday =3D CMOS_READ(RTC_DAY_OF_WEEK); > } > rtc_tm->tm_yday =3D 0; > rtc_tm->tm_isdst =3D 0; >=20 > rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx);=20 > =20 > return uip; > } > //---------------------------------------------------------------------= ------------------------ > =20 > Data are read on MC146818A chipset, documentaton of this chipset > explain that an update cycle is execute > once per second and during this update RTC_values or not fully > available. > So, we test the uip,when uip=3D=3D0 the update cycle is not in progress= and > will not be for at least 244 us (for all time bases). > =20 > So to be sure that in thoses 244 us i've time to execute my code, i've > disable the premption with rtdm_lock_get_irqsave. > But sometime, like if the update cycle begin in the midle of my code, i= > read bad value (value 165 exactly). > =20 > For example i read this bad time :=20 > "19/04/07 11:165:165 day 165" (like if i've been prempt after > CMOS_READ(RTC_HOURS) instructions). > or > "19//04/165 165:165:165 day 165" (like if i've been prempt after > CMOS_READ(RTC_MONTH) instructions). > =20 > We use the same hardware with other system (RTLinux), with same test on= > uip bit and we have no problem ( problem isn't on the chipset .. ). > =20 > So Is my rtdm_lock_get_irqsave and restore use correct ? > Is it sure that my critical section is protected from any premption > with this lock ? rtdm_lock_get_irqsave protects against preemption, but did you check o how CMOS_READ is realised internally? o if there are other CMOS_xxx users in the stock kernel that can bite you? As I already explained to you earlier, the CMOS access itself is problematic because it contains non-atomic operations that must be protected against re-entrance. Linux does this via local_irq_save/restore etc. Xenomai breaks this mechanism by making Linux fully preemptible. Even worse, your invocation of CMOS_READ in Xenomai context also invokes Linux local_irq_restore, potentially causing unwanted side effects. The Linux preemptibility issue applies to RTLinux as well, just how local_irq_save/restore behaves when being invoked from incorrect context may differ and explain the observed behaviour. Jan --------------enig883458611CDB7CE8E89149FA Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGJ1ieniDOoMHTA+kRAizrAJ90mGMNUB8XMxyKC795GXRkMLgNjwCcCAb8 QdWx0M4ovSkN2RrG2LtKbL8= =HJxG -----END PGP SIGNATURE----- --------------enig883458611CDB7CE8E89149FA-- From mboxrd@z Thu Jan 1 00:00:00 1970 Message-Id: Date: Thu, 19 Apr 2007 16:03:45 +0200 From: "Nicolas BLANCHARD" Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="=__PartAE89C2D1.0__=" Subject: Re: [Xenomai-help] [RTDM] IRQ lock problem ? List-Id: Help regarding installation and common use of Xenomai List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: jan.kiszka@domain.hid Cc: xenomai@xenomai.org --=__PartAE89C2D1.0__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit >>>> Jan Kiszka 19.04 13:55 >>> >Nicolas BLANCHARD wrote: >> Hi, >> >> I've write an rtdm driver and i have a problem. >> I use ioctl (rt_dev_ioctl) to read and write data (RTC time) on cmos. >> (I know it could better to use _rt_dev_read or rt_dev_write >> but it was my first rtdm driver, and i' think that it's not the cause >> of my problem). >> >> My user application (Native xenomai task) use this rt_dev_ioctl each >> 100 ms to read data on cmos. >> But, sometime (each 3 or 4 days), i read bad values. >> >> this is the code to read the cmos (call in an rt_dev_ioctl) : >> >> //--------------------------------------------------------------------------------------------- >> static unsigned char get_cmos_time(struct rtc146818drv_context *ctx, >> struct rtc_time *rtc_tm) >> { >> unsigned char uip; >> rtdm_lockctx_t lock_ctx; >> >> rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); >> >> uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); >> >> if(uip == 0) >> { >> rtc_tm->tm_year = CMOS_READ(RTC_YEAR); >> rtc_tm->tm_mon = CMOS_READ(RTC_MONTH); >> rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); >> rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); >> rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); >> rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); >> rtc_tm->tm_wday = CMOS_READ(RTC_DAY_OF_WEEK); >> } >> rtc_tm->tm_yday = 0; >> rtc_tm->tm_isdst = 0; >> >> rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); >> >> return uip; >> } >> //--------------------------------------------------------------------------------------------- >> >> Data are read on MC146818A chipset, documentaton of this chipset >> explain that an update cycle is execute >> once per second and during this update RTC_values or not fully >> available. >> So, we test the uip,when uip==0 the update cycle is not in progress and >> will not be for at least 244 us (for all time bases). >> >> So to be sure that in thoses 244 us i've time to execute my code, i've >> disable the premption with rtdm_lock_get_irqsave. >> But sometime, like if the update cycle begin in the midle of my code, i >> read bad value (value 165 exactly). >> >> For example i read this bad time : >> "19/04/07 11:165:165 day 165" (like if i've been prempt after >> CMOS_READ(RTC_HOURS) instructions). >> or >> "19//04/165 165:165:165 day 165" (like if i've been prempt after >> CMOS_READ(RTC_MONTH) instructions). >> >> We use the same hardware with other system (RTLinux), with same test on >> uip bit and we have no problem ( problem isn't on the chipset .. ). >> >> So Is my rtdm_lock_get_irqsave and restore use correct ? >> Is it sure that my critical section is protected from any premption >> with this lock ? > >rtdm_lock_get_irqsave protects against preemption, but did you check > >o how CMOS_READ is realised internally? >o if there are other CMOS_xxx users in the stock kernel that can bite > you? > >As I already explained to you earlier, the CMOS access itself is >problematic because it contains non-atomic operations that must be >protected against re-entrance. Linux does this via >local_irq_save/restore etc. Xenomai breaks this mechanism by making >Linux fully preemptible. Even worse, your invocation of CMOS_READ in >Xenomai context also invokes Linux local_irq_restore, potentially >causing unwanted side effects. > Ok, that right. CMOS_READ call local_irq_save and local_irq_restore. I've write my CMOS_READ function ... without those local_irq_ call. It's on test. >The Linux preemptibility issue applies to RTLinux as well, just how >local_irq_save/restore behaves when being invoked from incorrect >context may differ and explain the observed behaviour. > >Jan > With RtLinux we used rtl_crtical and rtl_end_crtical functions, after some define and macro i can see that it corresponding on cli ans sti processor instructions. In this case, if local_irq_ call on CMOS_READ have no negative effect it's perhaps because those calls have been changed by the rtlinux patch. I was thinking that with xenomai, all local_irq_ call are catch by the adeos layer and just the rtdm_lock_irq could make cli and sti processor instructions ... But it seems to be different. I'm not very experimented with thoses concepts (that why i' have not understand your previous explanation :-) ). thanks a lot. blanchard nicolas --=__PartAE89C2D1.0__= Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Description: HTML
>>>>= Jan=20 Kiszka <jan.kiszka@domain.hid> 19.04 13:55 >>>
>Nicolas BLANCHARD wrote:
>> Hi,
>>  =
>>=20 I've write an rtdm driver and i have a problem.
>> I use ioctl=20 (rt_dev_ioctl) to read and write data (RTC time) on cmos.
>> (I = know=20 it could better to use _rt_dev_read or rt_dev_write
>>  but = it=20 was my first rtdm driver, and i' think that it's not the cause
>> = of my=20 problem).
>> 
>> My user application (Native = xenomai=20 task) use this rt_dev_ioctl each
>> 100 ms to read data on=20 cmos.
>> But, sometime (each 3 or 4 days), i read bad=20 values.
>> 
>> this is the code to read the cmos = (call=20 in an rt_dev_ioctl) :
>> 
>>=20 //-------------------------------------------------------------------------= --------------------
>>=20 static unsigned char get_cmos_time(struct rtc146818drv_context=20 *ctx,
>>         &nbs= p; =20 struct rtc_time *rtc_tm)
>> {
>>  unsigned char=20 uip;
>>  rtdm_lockctx_t  lock_ctx;
>> =20
>>  rtdm_lock_get_irqsave(&ctx->lock, lock_ctx);=20
>> 
>>  uip =3D (CMOS_READ(RTC_FREQ_SELECT) = &=20 RTC_UIP);
>> 
>>  if(uip =3D=3D 0)
>>=  =20 {
>>       rtc_tm->tm_year = =3D=20 CMOS_READ(RTC_YEAR);
>>      =20 rtc_tm->tm_mon =3D=20 CMOS_READ(RTC_MONTH);
>>      =20 rtc_tm->tm_mday =3D=20 CMOS_READ(RTC_DAY_OF_MONTH);
>>      = ;=20 rtc_tm->tm_hour =3D=20 CMOS_READ(RTC_HOURS);
>>      =20 rtc_tm->tm_min =3D=20 CMOS_READ(RTC_MINUTES);
>>      =20 rtc_tm->tm_sec =3D=20 CMOS_READ(RTC_SECONDS);
>>      =20 rtc_tm->tm_wday =3D CMOS_READ(RTC_DAY_OF_WEEK);
>> }
>>= ;=20 rtc_tm->tm_yday =3D 0;
>> rtc_tm->tm_isdst =3D 0;
>>= ;=20
>> rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx);=20
>> 
>> return uip;
>> }
>>=20 //-------------------------------------------------------------------------= --------------------
>> =20
>> Data are read on MC146818A chipset, documentaton of this=20 chipset
>> explain that an update cycle is execute
>> = once per=20 second and during this update  RTC_values or not fully
>>=20 available.
>> So, we test the uip,when uip=3D=3D0 the update = cycle is not=20 in progress and
>> will not be for at least 244 us (for all = time=20 bases).
>> 
>> So to be sure that in thoses 244 us = i've=20 time to execute my code, i've
>> disable the premption with=20 rtdm_lock_get_irqsave.
>> But sometime, like if the update cycle = begin=20 in the midle of my code, i
>> read bad value (value 165=20 exactly).
>> 
>> For example i read this bad time = :=20
>> "19/04/07 11:165:165 day 165" (like if i've been prempt=20 after
>> CMOS_READ(RTC_HOURS) instructions).
>> = or
>>=20 "19//04/165 165:165:165 day 165" (like if i've been prempt after
>>= ;=20 CMOS_READ(RTC_MONTH) instructions).
>> 
>> We use = the=20 same hardware with other system (RTLinux), with same test on
>> = uip bit=20 and we have no problem ( problem isn't on the chipset .. ).
>>&nbs= p;=20
>> So Is my rtdm_lock_get_irqsave and restore use correct=20 ?
>> Is it sure that my critical section is protected from any=20 premption
>> with this lock ?
>
>rtdm_lock_get_irqsave= =20 protects against preemption, but did you check
>
>o how = CMOS_READ is=20 realised internally?
>o if there are other CMOS_xxx users in the = stock=20 kernel that can bite
>   you?
>
>As I = already=20 explained to you earlier, the CMOS access itself is
>problematic = because=20 it contains non-atomic operations that must be
>protected against=20 re-entrance. Linux does this via
>local_irq_save/restore etc. = Xenomai=20 breaks this mechanism by making
>Linux fully preemptible. Even = worse, your=20 invocation of CMOS_READ in
>Xenomai context also invokes Linux=20 local_irq_restore, potentially
>causing unwanted side=20 effects.
>
 
Ok, that right.
CMOS_READ call local_irq_save and local_irq_restore.
I've write my CMOS_READ function ... without those local_irq_ call. = It's on=20 test. 

>The Linux preemptibility issue applies to RTLinux as well, = just=20 how
>local_irq_save/restore behaves when being invoked from=20 incorrect
>context may differ and explain the observed behaviour.
>
>Jan
>
 
With RtLinux we used rtl_crtical and rtl_end_crtical functions,=20 after some define and macro
i can see that it corresponding on cli ans sti processor instructions.= In=20 this case, if local_irq_ call
on CMOS_READ have no negative effect it's perhaps because those=20 calls have been changed by the rtlinux patch.
 
I was thinking that with xenomai, all local_irq_ call are catch = by the=20 adeos layer and just the rtdm_lock_irq could
make cli and sti processor instructions ... But it seems to be = different.=20 I'm not very experimented with thoses concepts
(that why i' have not understand your previous explanation :-) = ).
 
thanks a lot.
blanchard nicolas
--=__PartAE89C2D1.0__=--