public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [LTP] [RFC] Timer related syscalls for LTP test
@ 2010-05-27 11:10 Suzuki Poulose
  2010-05-28  7:32 ` Subrata Modak
  0 siblings, 1 reply; 2+ messages in thread
From: Suzuki Poulose @ 2010-05-27 11:10 UTC (permalink / raw)
  To: Linus Test Project; +Cc: Josh Boyer, iranna.ankad

[-- Attachment #1: Type: text/plain, Size: 3407 bytes --]

Hi,

I have found a problem with the timer related syscall tests.

The following syscall tests, uses the direct syscall interface to the 
kernel for testing the interface, instead of using the GLIBC interface.

testcases/kernel/syscalls
	\_ timer_getoverrun/
	\_ timer_gettime/

testcases/kernel/timers
	\_ timer_create/
	\_ timer_delete/
	\_ timer_settime/

So they use :
	syscall(__NR_timer_XXXX, args )
for directly using the kernel syscall interface than using the

	timer_xxxxx(args)

provided by the GLIBC. This is completely fine.

But however there is a mismatch in the "timer_t" type defined by the 
Linux kernel and the GNU Libc.

Linux kernel defines it as an int for all architectures.

include/linux/types.h :

typedef __kernel_timer_t timer_t;

arch/powerpc/include/asm/posix_types.h :
typedef int __kernel_timer_t;


Now, the glibc provides a wrapper to the timer related system calls. 
While providing the wrapper, Glibc stores some internal data associated 
with the timer. So it defines the "timer_t" as a pointer (void*) as below:

/usr/include/time.h :

/* Timer ID returned by `timer_create'.  */
typedef __timer_t timer_t;


in /usr/include/bits/types.h :

/* Timer ID returned by `timer_create'.  */
__STD_TYPE __TIMER_T_TYPE __timer_t;

in /usr/include/bits/typesizes.h

#define __TIMER_T_TYPE          void *


So that leads to the definiton of timer_t as void* by glibc. And this 
cannot be changed. But the glibc uses the "proper" typed argument for 
the syscalls it issues by defining a kernel_timer_t.

On 32bit machines the difference is not noticed, since both the timer_t 
in userspace and the kernel space are of the same size. But on 64bit 
machines this is different.

Userspace has a width of 64bit and the kernel has 32bit width. Now, when 
we pass the pointer to timer_t to the kernel, things get complicated and 
on Big endian machines, ppc64, s390x, this leads to a problem. As the 
value kept is not available when we try to dereference it as a 32bit and 
this leads to undesired results like below:

timer_getoverrun01    1  TFAIL  :  Block 1: test 0 FAILED... errno = 22 
:Invalid argument


strace shows :


13017 timer_create(CLOCK_REALTIME, {(nil), SIGALRM, SIGEV_SIGNAL, 
{...}},{0x26e80}) = 0
13017 fstat(1, {st_dev=makedev(0, 11), st_ino=3, st_mode=S_IFCHR|0620,
st_nlink=1, st_uid=0, st_gid=5, st_blksize=1024, st_blocks=0, 
st_rdev=makedev(136, 0), 
st_atime=2010/05/17-15:48:40,st_mtime=2010/05/17-15:48:40, 
st_ctime=2010/05/17-13:15:48}) = 0
13017 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 
-1, 0)= 0x20000028000
13017 write(1, "timer_getoverrun01    0  TINFO  "..., 66) = 66
13017 timer_getoverrun(0x26e80)         = -1 EINVAL (Invalid argument)


So the conclusion is that, if we are using the System calls directly, we 
should use the argument which is compatible with the kernel. We simply 
*cannot* use the glibc definition and the kernel API directly.

I have a patch attached below that fixes this issue.

One more comment regarding the placement of timer_gettime and 
timer_getoverrun syscall tests. I strongly believe they could be moved 
to testcases/kernel/timers/ directory where the rest of the timer 
related syscall tests are placed. If that change is made, we can use the 
definition added in common_timers.h (in the patch) for those tests too, 
instead of defining in each of the tests.


Thanks

Suzuki









[-- Attachment #2: fix-timer_t-definition-for-syscall-tests.diff --]
[-- Type: text/plain, Size: 9270 bytes --]

Signed-off-by: Suzuki K P <suzuki@in.ibm.com>

Fix timer_t argument for timer related direct syscalls.

The tests timer_getoverrun and timer_gettime should be moved to testcases/kernel/timers
directory. If that is done, then we could use the definition in the common_timers.h, like
the other tests.

 /*  Description */
There is a mismatch in the "timer_t" type defined by the Linux kernel and the GNU Libc.

Linux kernel defines it as an int for all architectures.

include/linux/types.h :  

typedef __kernel_timer_t timer_t;

arch/powerpc/include/asm/posix_types.h : 
typedef int __kernel_timer_t;


Now, the glibc provides a wrapper to the timer related system calls. While providing the wrapper, Glibc stores some internal data associated with the timer. So it defines the "timer_t" as a pointer (void*) as below:

/usr/include/time.h :

/* Timer ID returned by `timer_create'.  */
typedef __timer_t timer_t;


in /usr/include/bits/types.h :

/* Timer ID returned by `timer_create'.  */
__STD_TYPE __TIMER_T_TYPE __timer_t;

in /usr/include/bits/typesizes.h

#define __TIMER_T_TYPE          void *


So that leads to the definiton of timer_t as void* by glibc. And this cannot be changed. But the glibc uses the "proper" typed argument for the syscalls it issues by defining a kernel_timer_t.

On 32bit machines the difference is not noticed, since both the timer_t in userspace and the kernel space are of the same size. But on 64bit machines this is different.

Userspace has a width of 64bit and the kernel has 32bit width. Now, when we pass the pointer to timer_t to the kernel, things get complicated and on Big endian machines, ppc64, s390x, this leads to a problem. As the value kept is not available when we try to dereference it as a 32bit and this leads to undesired results

Index: ltp/testcases/kernel/syscalls/timer_getoverrun/timer_getoverrun01.c
===================================================================
--- ltp.orig/testcases/kernel/syscalls/timer_getoverrun/timer_getoverrun01.c	2009-05-21 18:41:36.000000000 +0000
+++ ltp/testcases/kernel/syscalls/timer_getoverrun/timer_getoverrun01.c	2010-05-27 13:46:55.000000000 +0000
@@ -49,6 +49,11 @@
 #include "usctest.h"
 #include "linux_syscall_numbers.h"
 
+/* timer_t in kernel(int) is different from  Glibc definition(void*).
+ * Use the kernel definition.
+ */
+typedef int kernel_timer_t;
+
 /* Extern Global Variables */
 extern int Tst_count;           /* counter for tst_xxx routines.         */
 extern char *TESTDIR;           /* temporary dir created by tst_tmpdir() */
@@ -120,7 +125,7 @@
 int main(int ac, char **av) {
         int lc;                 /* loop counter */
         char *msg;              /* message returned from parse_opts */
-	timer_t created_timer_id;
+	kernel_timer_t created_timer_id;
         struct sigevent ev;
 	
         /* parse standard options */
Index: ltp/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
===================================================================
--- ltp.orig/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c	2009-05-21 18:43:48.000000000 +0000
+++ ltp/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c	2010-05-27 13:47:25.000000000 +0000
@@ -48,6 +48,11 @@
 #include "usctest.h"
 #include "linux_syscall_numbers.h"
 
+/* timer_t in kernel(int) is different from  Glibc definition(void*).
+ * Use the kernel definition.
+ */
+typedef int kernel_timer_t;
+
 /* Extern Global Variables */
 extern int Tst_count;           /* counter for tst_xxx routines.         */
 extern char *TESTDIR;           /* temporary dir created by tst_tmpdir() */
@@ -122,7 +127,7 @@
         int lc;                 /* loop counter */
         char *msg;              /* message returned from parse_opts */
 
-        timer_t created_timer_id;
+        kernel_timer_t created_timer_id;
         struct sigevent ev;
         struct itimerspec spec;
 
Index: ltp/testcases/kernel/timers/timer_delete/timer_delete02.c
===================================================================
--- ltp.orig/testcases/kernel/timers/timer_delete/timer_delete02.c	2009-12-06 20:53:44.000000000 +0000
+++ ltp/testcases/kernel/timers/timer_delete/timer_delete02.c	2010-05-27 14:01:21.000000000 +0000
@@ -84,7 +84,7 @@
 {
 	int lc;		/* loop counter */
 	char *msg;	/* message returned from parse_opts */
-	timer_t timer_id;
+	kernel_timer_t timer_id;
 
 	/* parse standard options */
 	if ((msg = parse_opts (ac, av, (option_t *) NULL, NULL)) !=
Index: ltp/testcases/kernel/timers/timer_delete/timer_delete03.c
===================================================================
--- ltp.orig/testcases/kernel/timers/timer_delete/timer_delete03.c	2009-12-06 20:53:44.000000000 +0000
+++ ltp/testcases/kernel/timers/timer_delete/timer_delete03.c	2010-05-27 14:01:35.000000000 +0000
@@ -73,7 +73,7 @@
 #include "usctest.h"
 #include "common_timers.h"
 
-#define INVALID_ID ((timer_t)-1)
+#define INVALID_ID ((kernel_timer_t)-1)
 
 static void setup();
 
Index: ltp/testcases/kernel/timers/timer_create/timer_create02.c
===================================================================
--- ltp.orig/testcases/kernel/timers/timer_create/timer_create02.c	2010-05-19 06:19:20.000000000 +0000
+++ ltp/testcases/kernel/timers/timer_create/timer_create02.c	2010-05-27 14:00:08.000000000 +0000
@@ -86,7 +86,7 @@
 {
 	int lc, i, j;		/* loop counter */
 	char *msg;			/* message returned from parse_opts */
-	timer_t created_timer_id;	/* holds the returned timer_id */
+	kernel_timer_t created_timer_id;	/* holds the returned timer_id */
 	char *message[3] = {
 		"SIGEV_SIGNAL",
 		"NULL",
Index: ltp/testcases/kernel/timers/timer_create/timer_create03.c
===================================================================
--- ltp.orig/testcases/kernel/timers/timer_create/timer_create03.c	2009-12-06 20:53:44.000000000 +0000
+++ ltp/testcases/kernel/timers/timer_create/timer_create03.c	2010-05-27 14:00:47.000000000 +0000
@@ -100,7 +100,7 @@
 {
 	int lc, i;			/* loop counter */
 	char *msg;			/* message returned from parse_opts */
-	timer_t created_timer_id;	/* holds the returned timer_id */
+	kernel_timer_t created_timer_id;	/* holds the returned timer_id */
 	char *message[] = {
 		"SIGEV_SIGNAL",
 		"NULL",
Index: ltp/testcases/kernel/timers/timer_create/timer_create04.c
===================================================================
--- ltp.orig/testcases/kernel/timers/timer_create/timer_create04.c	2009-12-06 20:53:44.000000000 +0000
+++ ltp/testcases/kernel/timers/timer_create/timer_create04.c	2010-05-27 14:01:05.000000000 +0000
@@ -111,7 +111,7 @@
 {
 	int lc, i;			/* loop counter */
 	char *msg;			/* message returned from parse_opts */
-	timer_t timer_id, *temp_id;	/* stores the returned timer_id */
+	kernel_timer_t timer_id, *temp_id;	/* stores the returned timer_id */
 	struct sigevent *temp_ev;	/* used for bad address test case */
 
 	clockid_t clocks[6] = {
@@ -158,7 +158,7 @@
 
 			switch (i) {
 			case 2: /* make the timer_id bad address */
-				temp_id = (timer_t *) -1;
+				temp_id = (kernel_timer_t *) -1;
 				break;
 			case 3:
 				/* make the event bad address */
@@ -167,7 +167,7 @@
 			case 4:
 				/* Produce an invalid timer_id address. */
 				if(tst_kvercmp(2, 6, 12) >= 0)
-					temp_id = (timer_t *) -1;
+					temp_id = (kernel_timer_t *) -1;
 				break;
 			case 5:
 				/* Produce an invalid event address. */
Index: ltp/testcases/kernel/timers/timer_settime/timer_settime02.c
===================================================================
--- ltp.orig/testcases/kernel/timers/timer_settime/timer_settime02.c	2009-12-06 20:53:44.000000000 +0000
+++ ltp/testcases/kernel/timers/timer_settime/timer_settime02.c	2010-05-27 14:01:53.000000000 +0000
@@ -81,7 +81,7 @@
 extern int Tst_count;		/* Test Case counter for tst_* routines */
 
 static struct itimerspec new_set, old_set, *old_temp;
-static timer_t timer;
+static kernel_timer_t timer;
 static int flag;
 
 int
Index: ltp/testcases/kernel/timers/timer_settime/timer_settime03.c
===================================================================
--- ltp.orig/testcases/kernel/timers/timer_settime/timer_settime03.c	2009-12-06 20:53:44.000000000 +0000
+++ ltp/testcases/kernel/timers/timer_settime/timer_settime03.c	2010-05-27 14:02:03.000000000 +0000
@@ -81,7 +81,7 @@
 extern int Tst_count;		/* Test Case counter for tst_* routines */
 
 static struct itimerspec new_set, old_set, *old_temp, *new_temp;
-static timer_t timer, tim;
+static kernel_timer_t timer, tim;
 
 static int exp_enos[] = {EINVAL, EFAULT, 0};
 
@@ -168,7 +168,7 @@
 		break;
 	case 3:
 		/* make timer_id invalid */
-		tim = (timer_t)-1;
+		tim = (kernel_timer_t)-1;
 		new_set.it_value.tv_nsec = 0;
 		break;
 	case 4:
Index: ltp/testcases/kernel/timers/include/common_timers.h
===================================================================
--- ltp.orig/testcases/kernel/timers/include/common_timers.h	2010-05-19 06:19:20.000000000 +0000
+++ ltp/testcases/kernel/timers/include/common_timers.h	2010-05-27 14:02:50.000000000 +0000
@@ -63,4 +63,9 @@
 #include <time.h>
 #include <unistd.h>
 
+/* timer_t in kernel(int) is different from  Glibc definition(void*).
+ * Use the kernel definition for syscall tests
+ */
+typedef int kernel_timer_t;
+
 #endif

[-- Attachment #3: Type: text/plain, Size: 80 bytes --]

------------------------------------------------------------------------------


[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [LTP] [RFC] Timer related syscalls for LTP test
  2010-05-27 11:10 [LTP] [RFC] Timer related syscalls for LTP test Suzuki Poulose
@ 2010-05-28  7:32 ` Subrata Modak
  0 siblings, 0 replies; 2+ messages in thread
From: Subrata Modak @ 2010-05-28  7:32 UTC (permalink / raw)
  To: Suzuki Poulose; +Cc: Linus Test Project, Josh Boyer, iranna.ankad

On Thu, 2010-05-27 at 16:40 +0530, Suzuki Poulose wrote: 
> Hi,
> 
> I have found a problem with the timer related syscall tests.
> 
> The following syscall tests, uses the direct syscall interface to the 
> kernel for testing the interface, instead of using the GLIBC interface.
> 
> testcases/kernel/syscalls
> 	\_ timer_getoverrun/
> 	\_ timer_gettime/
> 
> testcases/kernel/timers
> 	\_ timer_create/
> 	\_ timer_delete/
> 	\_ timer_settime/
> 
> So they use :
> 	syscall(__NR_timer_XXXX, args )
> for directly using the kernel syscall interface than using the
> 
> 	timer_xxxxx(args)
> 
> provided by the GLIBC. This is completely fine.
> 
> But however there is a mismatch in the "timer_t" type defined by the 
> Linux kernel and the GNU Libc.
> 
> Linux kernel defines it as an int for all architectures.
> 
> include/linux/types.h :
> 
> typedef __kernel_timer_t timer_t;
> 
> arch/powerpc/include/asm/posix_types.h :
> typedef int __kernel_timer_t;
> 
> 
> Now, the glibc provides a wrapper to the timer related system calls. 
> While providing the wrapper, Glibc stores some internal data associated 
> with the timer. So it defines the "timer_t" as a pointer (void*) as below:
> 
> /usr/include/time.h :
> 
> /* Timer ID returned by `timer_create'.  */
> typedef __timer_t timer_t;
> 
> 
> in /usr/include/bits/types.h :
> 
> /* Timer ID returned by `timer_create'.  */
> __STD_TYPE __TIMER_T_TYPE __timer_t;
> 
> in /usr/include/bits/typesizes.h
> 
> #define __TIMER_T_TYPE          void *
> 
> 
> So that leads to the definiton of timer_t as void* by glibc. And this 
> cannot be changed. But the glibc uses the "proper" typed argument for 
> the syscalls it issues by defining a kernel_timer_t.
> 
> On 32bit machines the difference is not noticed, since both the timer_t 
> in userspace and the kernel space are of the same size. But on 64bit 
> machines this is different.
> 
> Userspace has a width of 64bit and the kernel has 32bit width. Now, when 
> we pass the pointer to timer_t to the kernel, things get complicated and 
> on Big endian machines, ppc64, s390x, this leads to a problem. As the 
> value kept is not available when we try to dereference it as a 32bit and 
> this leads to undesired results like below:
> 
> timer_getoverrun01    1  TFAIL  :  Block 1: test 0 FAILED... errno = 22 
> :Invalid argument
> 
> 
> strace shows :
> 
> 
> 13017 timer_create(CLOCK_REALTIME, {(nil), SIGALRM, SIGEV_SIGNAL, 
> {...}},{0x26e80}) = 0
> 13017 fstat(1, {st_dev=makedev(0, 11), st_ino=3, st_mode=S_IFCHR|0620,
> st_nlink=1, st_uid=0, st_gid=5, st_blksize=1024, st_blocks=0, 
> st_rdev=makedev(136, 0), 
> st_atime=2010/05/17-15:48:40,st_mtime=2010/05/17-15:48:40, 
> st_ctime=2010/05/17-13:15:48}) = 0
> 13017 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 
> -1, 0)= 0x20000028000
> 13017 write(1, "timer_getoverrun01    0  TINFO  "..., 66) = 66
> 13017 timer_getoverrun(0x26e80)         = -1 EINVAL (Invalid argument)
> 
> 
> So the conclusion is that, if we are using the System calls directly, we 
> should use the argument which is compatible with the kernel. We simply 
> *cannot* use the glibc definition and the kernel API directly.
> 
> I have a patch attached below that fixes this issue.

Thanks Suzie.

> 
> One more comment regarding the placement of timer_gettime and 
> timer_getoverrun syscall tests. I strongly believe they could be moved 
> to testcases/kernel/timers/ directory where the rest of the timer 
> related syscall tests are placed. If that change is made, we can use the 
> definition added in common_timers.h (in the patch) for those tests too, 
> instead of defining in each of the tests.

Sure, you can move them accordingly in the next patch :-)

Regards--
Subrata

> 
> 
> Thanks
> 
> Suzuki
> 
> 
> 
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------------
> 
> _______________________________________________
> Ltp-list mailing list
> Ltp-list@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/ltp-list


------------------------------------------------------------------------------

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-05-29 18:23 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-27 11:10 [LTP] [RFC] Timer related syscalls for LTP test Suzuki Poulose
2010-05-28  7:32 ` Subrata Modak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox