Re: [Fwd: Re: [patch] Real-Time Preemption, -RT-2.6.9-mm1-V0.4]

Ingo Molnar
2004-10-29T16:17:27Z

* Ingo Molnar <mingo@elte.hu> wrote:

> ahh ... the ioctls. All ioctls in Linux take the 'big kernel lock'. So
> if jackd calls an ioctl() in the fastpath then that could easily get
> delayed. Also, there are a couple of other syscalls too that touch the
> BKL, so an strace of the 'jackd latency path' would be quite useful.

i straced jackd and it seems to do ioctls:

5971 ioctl(7, 0x4143, 0x446b7d3c) = 0
5971 ioctl(7, 0x4140, 0x446b7d3c) = 0
5971 ioctl(7, 0x4142, 0x446b7d3c) = 0
5971 poll([{fd=7, events=POLLOUT|POLLERR|POLLNVAL, revents=POLLOUT}], 1, 4353) = 1
5971 poll([{fd=7, events=POLLOUT|POLLERR|POLLNVAL, revents=POLLOUT}], 1, 4353)= 1
5971 poll([{fd=7, events=POLLOUT|POLLERR|POLLNVAL, revents=POLLOUT|POLLERR}], 1, 4353) = 1
5971 ioctl(7, 0x806c4120, 0xb77bb960) = 0
5971 gettimeofday({1099064915, 776665}, NULL) = 0

the BKL can generate arbitrary latencies. Anything up to 100-200
milliseconds. Rui, Florian, could you try the quick hack below?

Ingo

--- linux/fs/ioctl.c.orig2
+++ linux/fs/ioctl.c
@@ -68,19 +68,26 @@ asmlinkage long sys_ioctl(unsigned int f
goto out;
}

- lock_kernel();
switch (cmd) {
case FIOCLEX:
+ lock_kernel();
set_close_on_exec(fd, 1);
+ unlock_kernel();
break;

case FIONCLEX:
+ lock_kernel();
set_close_on_exec(fd, 0);
+ unlock_kernel();
break;

case FIONBIO:
- if ((error = get_user(on, (int __user *)arg)) != 0)
+ lock_kernel();
+ unlock_kernel();
+ if ((error = get_user(on, (int __user *)arg)) != 0) {
+ unlock_kernel();
break;
+ }
flag = O_NONBLOCK;
#ifdef __sparc__
/* SunOS compatibility item. */
@@ -91,11 +98,15 @@ asmlinkage long sys_ioctl(unsigned int f
filp->f_flags |= flag;
else
filp->f_flags &= ~flag;
+ unlock_kernel();
break;

case FIOASYNC:
- if ((error = get_user(on, (int __user *)arg)) != 0)
+ lock_kernel();
+ if ((error = get_user(on, (int __user *)arg)) != 0) {
+ unlock_kernel();
break;
+ }
flag = on ? FASYNC : 0;

/* Did FASYNC state change ? */
@@ -104,16 +115,20 @@ asmlinkage long sys_ioctl(unsigned int f
error = filp->f_op->fasync(fd, filp, on);
else error = -ENOTTY;
}
- if (error != 0)
+ if (error != 0) {
+ unlock_kernel();
break;
+ }

if (on)
filp->f_flags |= FASYNC;
else
filp->f_flags &= ~FASYNC;
+ unlock_kernel();
break;

case FIOQSIZE:
+ lock_kernel();
if (S_ISDIR(filp->f_dentry->d_inode->i_mode) ||
S_ISREG(filp->f_dentry->d_inode->i_mode) ||
S_ISLNK(filp->f_dentry->d_inode->i_mode)) {
@@ -122,6 +137,7 @@ asmlinkage long sys_ioctl(unsigned int f
}
else
error = -ENOTTY;
+ unlock_kernel();
break;
default:
error = -ENOTTY;
@@ -130,7 +146,6 @@ asmlinkage long sys_ioctl(unsigned int f
else if (filp->f_op && filp->f_op->ioctl)
error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
}
- unlock_kernel();
fput(filp);