Subject: ata ioctl call (and atactl(8)) causes system hangs
To: None <current-users@NetBSD.org>
From: Efstathios Kamperis <ekamperi@auth.gr>
List: current-users
Date: 08/22/2007 18:08:08
This message is in MIME format.
--=_72wakrr65paw
Content-Type: text/plain;
charset=ISO-8859-7;
DelSp="Yes";
format="flowed"
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Hello netbsders of the Globe (and of the ISS ;))
I was studying the atactl(8) code and came up with a code snippet that =20
would read the model of my hard disk. The program works fine, but =20
sometimes,
_especially_ under heavy load, it causes my system to hang.
First it (my program) goes into the 'vinvalbu' state:
618 root -5 0 88K 1016K vinvalbu 0:00 0.00% 0.00% a.out
Then syslogd occupies a significant amount of my CPU:
144 root 2 0 192K 944K kqread 0:11 18.07% 18.07% syslogd
And my system message buffer fills in with:
buffer still DELWRI
I mean a _lot_ of them:
[stathis@netbsd ~]$ dmesg | grep DELWRI | wc -l
819
Then my processes go into the vnlock state one after another. In the =20
meantime the system is still 'usable' depending on what processes have =20
locked. From that point on, it is only a matter of seconds, until all =20
processes have locked and I have to hard reset my pc.
As I've said before, this offending behaviour is exhibited only some =20
times, and under heavy load. To reproduce it, I run the following =20
script, and during it's execution, I start for example firefox.
#!/bin/sh
for i in `seq 1 1000`
do
echo $i
sudo ./a.out /dev/wd0a
done
I' ve noticed that running atactl /dev/wd0a identyfy in a tight loop =20
as above, also causes my system hang, but it does it instantaneously, =20
and I am unable to gather any further informationj (such as examine =20
the state of the process or the dmesg buffer).
I am running 4.99.29/i386, but I had the exact problems with =20
4.99.20/i386 as wel.
I attach you my code.
Best regards,
Stathis K
--=_72wakrr65paw
Content-Type: text/x-csrc;
charset=UTF-8;
name="readwd.c"
Content-Disposition: attachment;
filename="readwd.c"
Content-Transfer-Encoding: quoted-printable
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dev/ata/atareg.h>
#include <sys/ataio.h>
#include <sys/ioctl.h>
#include <sys/param.h>
int main(int argc, char *argv[])
{
int fd;
unsigned int i;
struct atareq req;
union {
unsigned char inbuf[DEV_BSIZE];
struct ataparams inqbuf;
} inbuf;
u_int16_t *p;
/* check argument count */
if (argc !=3D 2) {
fprintf(stderr, "usage: %s /dev/file\n", argv[0]);
exit(EXIT_FAILURE);
}
/* open device file descriptor */
if ((fd =3D open(argv[1], O_RDONLY)) =3D=3D -1) {
perror("open");
exit(EXIT_FAILURE);
}
/* construct an ata request */
memset(&req, 0, sizeof req);
req.flags =3D ATACMD_READ;
req.command =3D WDCC_IDENTIFY;
req.databuf =3D (caddr_t) &inbuf;
req.datalen =3D sizeof inbuf;
req.timeout =3D 1000; /* 1 sec */
/* make the ioctl call */
if (ioctl(fd, ATAIOCCOMMAND, &req) =3D=3D -1) {
perror("ioctl");
close(fd);
exit(EXIT_FAILURE);
}
/* close file descriptor */
close(fd);
return EXIT_SUCCESS;
}
--=_72wakrr65paw--