[SMP]: Big Kernel Lock vs ISR_Disable
Sebastian Huber
sebastian.huber at embedded-brains.de
Tue Sep 13 07:29:20 UTC 2011
Hello!
On 09/12/2011 08:25 PM, Marta Rybczynska wrote:
[...]
> Normally the code looks like this:
> --- git/cpukit/libfs/src/devfs/devfs_mknod.c 2011-08-22
> 21:10:06.230348773 +0200
> +++ rtems/cpukit/libfs/src/devfs/devfs_mknod.c 2011-08-22
> 21:13:41.265537357 +0200
> @@ -69,11 +69,13 @@ int devFS_mknod(
> rtems_set_errno_and_return_minus_one( ENOMEM );
>
> _ISR_Disable(level);
> + _Lock_Critical_Section();
> device_name_table[slot].device_name = (char *)path;
> device_name_table[slot].device_name_length = strlen(path);
Out of context: the strlen() inside the critical section is bad.
> device_name_table[slot].major = major;
> device_name_table[slot].minor = minor;
> device_name_table[slot].mode = mode;
> + _Unlock_Critical_Section();
> _ISR_Enable(level);
Does the _ISR_Disable/Enable still disable/enable interrupts on the executing
core? I suppose the lock used in _Lock/Unlock_Critical_Section uses a spin
lock and thus disables also the interrupts on the executing core? Is it a fair
lock?
Suppose the _ISR_Disable() still disables interrupts on the executing core,
then the maximum length of disabled interrupts on a single core depends on all
other cores and in particular the fairness of the lock. I think this is very
bad for a real-time system.
>
> return 0;
>
> In this case, it seems natural to merge _ISR_Disable and
> _Lock_Critical_Section into one function.
Yes, definitely.
>
> However, we do have more complicated cases:
> --- git/cpukit/posix/src/mutexlocksupp.c 2011-09-01
> 14:13:52.455646968 +0200
> +++ rtems/cpukit/posix/src/mutexlocksupp.c 2011-09-10
> 18:50:03.379722079 +0200
> @@ -43,6 +43,8 @@ int _POSIX_Mutex_Lock_support(
> Objects_Locations location;
> ISR_Level level;
>
> + _Lock_Critical_Section();
> +
> the_mutex = _POSIX_Mutex_Get_interrupt_disable( mutex,&location,
> &level );
> switch ( location ) {
>
> @@ -62,7 +64,8 @@ int _POSIX_Mutex_Lock_support(
> case OBJECTS_REMOTE:
> #endif
> case OBJECTS_ERROR:
> - break;
> + _Unlock_Critical_Section();
> + break;
> }
>
> return EINVAL;
>
> Here we have a side-effect of the _POSIX_Mutex_Get_interrupt_disable
> function.
Can't we move this into the _Object_Get() or _Objects_Get_isr_disable()? I
think the auto-initialization in the _POSIX_Mutex_Get_interrupt_disable() can
use its own critical section.
>
>
> The options we have are:
> 1. Add lock to _ISR_Disable/Enable
> This will break certain points, especially around _Objects_Get (the
> function exits in the critical section of Disable_Dispatch and it is up to
> the further code to release it, sometimes the code can sleep in the
> process).
Without much thinking I would prefer that option. This is similar to the Giant
lock in FreeBSD.
>
> 2. Add a level parameter to our
> _Lock_Critical_Section/_Unlock_Critical_Section functions and call SMP lock
> inside
> However, this will lead to unnecessary recursive interrupt disable
I suppose this may lead to potentially unbounded interrupt disable times.
>
> 3. Add an SMP lock variant that does not disable the interrupts
Is this possible?
Kind regards,
Sebastian
--
Sebastian Huber, embedded brains GmbH
Address : Obere Lagerstr. 30, D-82178 Puchheim, Germany
Phone : +49 89 18 90 80 79-6
Fax : +49 89 18 90 80 79-9
E-Mail : sebastian.huber at embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
More information about the users
mailing list