Skip to contentSkip to conversation

Performance Stats: Kernel patch

PATCH In review Maxim Uvarov 4 participants 11 messages May 8, 2007 – May 21, 2007

Subsystems (7)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Performance Stats: Kernel patch

Patch makes available to the user the following task and process performance statistics:
* Involuntary Context Switches (task_struct->nivcsw)
* Voluntary Context Switches (task_struct->nvcsw)
* Number of system calls (added new counter thread_info->sysall_count)

Statistics information is available from:
1. taskstats interface (Documentation/accounting/)
2. /proc/PID/status (task only).

This data is useful for detecting hyperactivity
patterns between processes.

---

 Documentation/accounting/getdelays.c          |   20 ++++++++++++++++++--
 Documentation/accounting/taskstats-struct.txt |    7 +++++++
 arch/i386/kernel/asm-offsets.c                |    1 +
 arch/i386/kernel/entry.S                      |    1 +
 arch/powerpc/kernel/asm-offsets.c             |    2 ++
 arch/powerpc/kernel/entry_32.S                |    5 +++++
 arch/powerpc/kernel/entry_64.S                |    5 +++++
 arch/x86_64/kernel/asm-offsets.c              |    1 +
 arch/x86_64/kernel/entry.S                    |    1 +
 fs/proc/array.c                               |   14 ++++++++++++++
 include/asm-i386/thread_info.h                |    1 +
 include/asm-powerpc/thread_info.h             |    1 +
 include/asm-x86_64/thread_info.h              |    1 +
 include/linux/taskstats.h                     |    6 +++++-
 kernel/fork.c                                 |    3 +++
 kernel/taskstats.c                            |    6 ++++++
 16 files changed, 72 insertions(+), 3 deletions(-)
Documentation/accounting/getdelays.c +18 -2
index e9126e7..1be7d65 100644
@@ -49,6 +49,7 @@ char name[100];
 int dbg;
 int print_delays;
 int print_io_accounting;
+int print_task_stats;
 __u64 stime, utime;
 
 #define PRINTF(fmt, arg...) {			\
@@ -187,7 +188,7 @@ void print_delayacct(struct taskstats *t)
 	       "IO    %15s%15s\n"
 	       "      %15llu%15llu\n"
 	       "MEM   %15s%15s\n"
-	       "      %15llu%15llu\n\n",
+	       "      %15llu%15llu\n"
 	       "count", "real total", "virtual total", "delay total",
 	       t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total,
 	       t->cpu_delay_total,
@@ -196,6 +197,15 @@ void print_delayacct(struct taskstats *t)
 	       "count", "delay total", t->swapin_count, t->swapin_delay_total);
 }
 
+void print_taskstats(struct taskstats *t)
+{
+	printf("\n\nTask  %15s%15s%15s\n"
+	       "      %15lu%15lu%15lu\n",
+	       "syscalls", "voluntary", "nonvoluntary",
+	       t->syscall_counter, t->nvcsw, t->nivcsw);
+
+}
+
 void print_ioacct(struct taskstats *t)
 {
 	printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n",
@@ -227,7 +237,7 @@ int main(int argc, char *argv[])
 	struct msgtemplate msg;
 
 	while (1) {
-		c = getopt(argc, argv, "diw:r:m:t:p:v:l");
+		c = getopt(argc, argv, "qdiw:r:m:t:p:v:l");
 		if (c < 0)
 			break;
 
@@ -240,6 +250,10 @@ int main(int argc, char *argv[])
 			printf("printing IO accounting\n");
 			print_io_accounting = 1;
 			break;
+		case 'q':
+			printf("printing task/process stasistics:\n");
+			print_task_stats = 1;
+			break;
 		case 'w':
 			strncpy(logfile, optarg, MAX_FILENAME);
 			printf("write to file %s\n", logfile);
@@ -381,6 +395,8 @@ int main(int argc, char *argv[])
 							print_delayacct((struct taskstats *) NLA_DATA(na));
 						if (print_io_accounting)
 							print_ioacct((struct taskstats *) NLA_DATA(na));
+						if (print_task_stats)
+							print_taskstats((struct taskstats *) NLA_DATA(na));
 						if (fd) {
 							if (write(fd, NLA_DATA(na), na->nla_len) < 0) {
 								err(1,"write error\n");
Documentation/accounting/taskstats-struct.txt +7 -0
index 661c797..5dac173 100644
@@ -22,6 +22,8 @@ There are three different groups of fields in the struct taskstats:
     /* Extended accounting fields end */
     Their values are collected if CONFIG_TASK_XACCT is set.
 
+4) Per-task and per-thread statistics
+
 Future extension should add fields to the end of the taskstats struct, and
 should not change the relative position of each field within the struct.
 
@@ -158,4 +160,9 @@ struct taskstats {
 
 	/* Extended accounting fields end */
 
+4) Per-task and per-thread statiscits
+	__u32	syscall_counter;	/* Syscall counter */
+	__u32	nvcsw;			/* Context voluntary switch counter */
+	__u32	nivcsw;			/* Context involuntary switch counter */
+
 }
arch/i386/kernel/asm-offsets.c +1 -0
index 1b2f3cd..4ad49d2 100644
@@ -56,6 +56,7 @@ void foo(void)
 	OFFSET(TI_addr_limit, thread_info, addr_limit);
 	OFFSET(TI_restart_block, thread_info, restart_block);
 	OFFSET(TI_sysenter_return, thread_info, sysenter_return);
+	OFFSET(TI_syscall_count, thread_info, syscall_count);
 	BLANK();
 
 	OFFSET(GDS_size, Xgt_desc_struct, size);
arch/i386/kernel/entry.S +1 -0
index 5e47683..26f0cc0 100644
@@ -331,6 +331,7 @@ sysenter_past_esp:
 	CFI_ADJUST_CFA_OFFSET 4
 	SAVE_ALL
 	GET_THREAD_INFO(%ebp)
+	incl	TI_syscall_count(%ebp)	# Increment syscalls counter
 
 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
 	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
arch/powerpc/kernel/asm-offsets.c +2 -0
index 030d300..b640039 100644
@@ -94,6 +94,8 @@ int main(void)
 	DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
 	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
 	DEFINE(TI_TASK, offsetof(struct thread_info, task));
+	DEFINE(TI_SYSCALL_COUNT, offsetof(struct thread_info, syscall_count));
+
 #ifdef CONFIG_PPC32
 	DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
 	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
arch/powerpc/kernel/entry_32.S +5 -0
index c03e829..329c2f8 100644
@@ -202,6 +202,11 @@ _GLOBAL(DoSyscall)
 	bl	do_show_syscall
 #endif /* SHOW_SYSCALLS */
 	rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
+#ifdef CONFIG_THREAD_PERF_STAT_SYSC
+	lwz r11,TI_SYSC_CNT(r10)
+	addi r11,r11,1
+	stw r11,TI_SYSC_CNT(r10)
+#endif /* CONFIG_THREAD_PERF_STAT_SYSC */
 	lwz	r11,TI_FLAGS(r10)
 	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
arch/powerpc/kernel/entry_64.S +5 -0
index 2551c08..5907f76 100644
@@ -115,6 +115,11 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 	addi	r9,r1,STACK_FRAME_OVERHEAD
 #endif
 	clrrdi	r11,r1,THREAD_SHIFT
+#ifdef CONFIG_TASKSTATS
+	ld r10,TI_SYSCALL_COUNT(r11)
+	addi r10,r10,1
+	std r10,TI_SYSCALL_COUNT(r11)
+#endif
 	ld	r10,TI_FLAGS(r11)
 	andi.	r11,r10,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
arch/x86_64/kernel/asm-offsets.c +1 -0
index 96687e2..da57356 100644
@@ -35,6 +35,7 @@ int main(void)
 	ENTRY(addr_limit);
 	ENTRY(preempt_count);
 	ENTRY(status);
+	ENTRY(syscall_count);
 	BLANK();
 #undef ENTRY
 #define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
arch/x86_64/kernel/entry.S +1 -0
index 9f5dac6..9fd97df 100644
@@ -229,6 +229,7 @@ ENTRY(system_call)
 	movq  %rcx,RIP-ARGOFFSET(%rsp)
 	CFI_REL_OFFSET rip,RIP-ARGOFFSET
 	GET_THREAD_INFO(%rcx)
+	addq $1, threadinfo_syscall_count(%rcx)   # Increment syscalls counter
 	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
 	jnz tracesys
 	cmpq $__NR_syscall_max,%rax
fs/proc/array.c +14 -0
index 70e4fab..30f6fd5 100644
@@ -290,6 +290,19 @@ static inline char *task_cap(struct task_struct *p, char *buffer)
 			    cap_t(p->cap_permitted),
 			    cap_t(p->cap_effective));
 }
+static inline char *task_perf(struct task_struct *p, char *buffer)
+{
+	/* Syscall counter adds 1 line overhead on each syscall execution
+	 * in entry.S, so probably it is the leave this stuff under ifdefs.
+	 */
+#ifdef CONFIG_TASKSTATS
+	buffer += sprintf(buffer, "Syscalls:\t%lu\n", p->thread_info->syscall_count);
+#endif
+	return buffer + sprintf(buffer, "Nvcsw:\t%lu\n"
+                           "Nivcsw:\t%lu\n",
+                           p->nvcsw,
+                           p->nivcsw);
+}
 
 int proc_pid_status(struct task_struct *task, char * buffer)
 {
@@ -309,6 +322,7 @@ int proc_pid_status(struct task_struct *task, char * buffer)
 #if defined(CONFIG_S390)
 	buffer = task_show_regs(task, buffer);
 #endif
+	buffer = task_perf(task, buffer);
 	return buffer - orig;
 }
 
include/asm-i386/thread_info.h +1 -0
index 4b187bb..bccfd6a 100644
@@ -33,6 +33,7 @@ struct thread_info {
 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
 
+	unsigned long		syscall_count;	/* Syscall counter */
 	mm_segment_t		addr_limit;	/* thread address space:
 					 	   0-0xBFFFFFFF for user-thead
 						   0-0xFFFFFFFF for kernel-thread
include/asm-powerpc/thread_info.h +1 -0
index 3f32ca8..5306ac2 100644
@@ -35,6 +35,7 @@ struct thread_info {
 	int		cpu;			/* cpu we're on */
 	int		preempt_count;		/* 0 => preemptable,
 						   <0 => BUG */
+	unsigned long	syscall_count;		/* Syscall counter */
 	struct restart_block restart_block;
 	unsigned long	local_flags;		/* private flags for thread */
 
include/asm-x86_64/thread_info.h +1 -0
index 74a6c74..e53022d 100644
@@ -31,6 +31,7 @@ struct thread_info {
 	__u32			cpu;		/* current CPU */
 	int 			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
+	unsigned long		syscall_count;	/* Syscall counter */
 	mm_segment_t		addr_limit;	
 	struct restart_block    restart_block;
 };
include/linux/taskstats.h +5 -1
index 3fced47..e3341b6 100644
@@ -31,7 +31,7 @@
  */
 
 
-#define TASKSTATS_VERSION	3
+#define TASKSTATS_VERSION	4
 #define TS_COMM_LEN		32	/* should be >= TASK_COMM_LEN
 					 * in linux/sched.h */
 
@@ -141,6 +141,10 @@ struct taskstats {
 	__u64	write_syscalls;		/* write syscalls */
 	/* Extended accounting fields end */
 
+	__u32  syscall_counter;   /* Syscall counter */
+	__u32  nvcsw;
+	__u32  nivcsw;
+
 #define TASKSTATS_HAS_IO_ACCOUNTING
 	/* Per-task storage I/O accounting starts */
 	__u64	read_bytes;		/* bytes of read I/O */
kernel/fork.c +3 -0
index fc723e5..5213738 100644
@@ -1042,6 +1042,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	p->wchar = 0;		/* I/O counter: bytes written */
 	p->syscr = 0;		/* I/O counter: read syscalls */
 	p->syscw = 0;		/* I/O counter: write syscalls */
+#ifdef CONFIG_TASKSTATS
+	p->thread_info->syscall_count = 0; /* Syscall counter: total numbers of syscalls */
+#endif
 	task_io_accounting_init(p);
 	acct_clear_integrals(p);
 
kernel/taskstats.c +6 -0
index 4c3476f..d7bf33f 100644
@@ -196,6 +196,9 @@ static int fill_pid(pid_t pid, struct task_struct *tsk,
 
 	/* fill in basic acct fields */
 	stats->version = TASKSTATS_VERSION;
+	stats->syscall_counter = tsk->thread_info->syscall_count;
+	stats->nvcsw = tsk->nvcsw;
+	stats->nivcsw = tsk->nivcsw;
 	bacct_add_tsk(stats, tsk);
 
 	/* fill in extended acct fields */
@@ -242,6 +245,9 @@ static int fill_tgid(pid_t tgid, struct task_struct *first,
 		 */
 		delayacct_add_tsk(stats, tsk);
 
+		stats->syscall_counter += tsk->thread_info->syscall_count;
+		stats->nvcsw += tsk->nvcsw;
+		stats->nivcsw += tsk->nivcsw;
 	} while_each_thread(first, tsk);
 
 	unlock_task_sighand(first, &flags);
maintainer
#1 lore raw
Quoted 7 lines · On Tue, 08 May 2007 16:26:51 +0000 Maxim Uvarov <[email protected]> wrote:

From: Maxim Uvarov <[email protected]>
To: Andrew Morton <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]

Strange that linux-ppc was the only mailing list you copied?

Quoted 12 lines

Subject: [PATCH] Performance Stats: Kernel patch
Date: Tue, 08 May 2007 16:26:51 +0000
User-Agent: StGIT/0.12.1

Patch makes available to the user the following task and process performance statistics:
* Involuntary Context Switches (task_struct->nivcsw)
* Voluntary Context Switches (task_struct->nvcsw)
* Number of system calls (added new counter thread_info->sysall_count)

Quoted 6 lines

Statistics information is available from:
1. taskstats interface (Documentation/accounting/)
2. /proc/PID/status (task only).

This data is useful for detecting hyperactivity
patterns between processes.

syscall entry is a super-hotpath and there will be a developer revolt if we go adding an incl to that path, sorry.

(Did that incl also cover the int 80 entry?)

#2 lore raw
Quoted 15 lines · Andrew Morton
Quoted 9 lines · On Tue, 08 May 2007 16:26:51 +0000 Maxim Uvarov <[email protected]> wrote:

From: Maxim Uvarov <[email protected]>
To: Andrew Morton <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]

Quoted 4 lines

Strange that linux-ppc was the only mailing list you copied?

Very strange. Possible stgit mail have limitation of CC.

Quoted 16 lines
Quoted 16 lines

Subject: [PATCH] Performance Stats: Kernel patch
Date: Tue, 08 May 2007 16:26:51 +0000
User-Agent: StGIT/0.12.1

Patch makes available to the user the following task and process performance statistics:
* Involuntary Context Switches (task_struct->nivcsw)
* Voluntary Context Switches (task_struct->nvcsw)
* Number of system calls (added new counter thread_info->sysall_count)

Statistics information is available from:
1. taskstats interface (Documentation/accounting/)
2. /proc/PID/status (task only).

Quoted 10 lines
Quoted 4 lines

This data is useful for detecting hyperactivity
patterns between processes.

syscall entry is a super-hotpath and there will be a developer revolt if we go adding an incl to that path, sorry.

Yes, I know that it is very critical part of code. May be protection with ifdef CONFIG_TASKSTATS in all entry.S can be solution?
In that case we can be sure that nothing wrong can not happen, and if this functionality is needed we can turn on this.

Quoted 3 lines

(Did that incl also cover the int 80 entry?)

Actually not. But counter increments each time when syscall calls. But it is in very save place, just after
SAVE_ALL
GET_THREAD_INFO(%ebp)
So it is very hard to break something.

(I'm going to update patch.)

maintainer
#3 lore raw
Quoted 9 lines · On Thu, 10 May 2007 11:11:18 +0000 Maxim Uvarov <[email protected]> wrote:
Quoted 5 lines

syscall entry is a super-hotpath and there will be a developer revolt if we go adding an incl to that path, sorry.

Yes, I know that it is very critical part of code. May be protection with ifdef CONFIG_TASKSTATS in all entry.S can be solution?
In that case we can be sure that nothing wrong can not happen, and if this functionality is needed we can turn on this.

I very much hope that all distributors will enable taskstats, so that won't help.

I don't think the syscall-counting feature has a future, sorry. Perhaps you could do something like hooking it up on-demand by insertion of a kprobe, dunno.

Quoted 9 lines
Quoted 3 lines

(Did that incl also cover the int 80 entry?)

Actually not. But counter increments each time when syscall calls. But it is in very save place, just after
SAVE_ALL
GET_THREAD_INFO(%ebp)
So it is very hard to break something.

What I meant was: the code appears to be counting sysenter-invoked syscalls, but it isn't counting not int 80-invoked syscalls.

#4 lore raw
Quoted 6 lines · Andrew Morton

What I meant was: the code appears to be counting sysenter-invoked syscalls, but it isn't counting not int 80-invoked syscalls.

You are right. Seems it should be added too.

#5 lore raw

Using kprobes [was Re: [PATCH] Performance Stats: Kernel patch

In reply to Andrew Morton
Quoted 4 lines · Andrew Morton

I don't think the syscall-counting feature has a future, sorry. Perhaps you could do something like hooking it up on-demand by insertion of a kprobe, dunno.

This is an interesting point. I've started fiddling with (a wrapper around) kprobes that allows me to pick any subroutine symbol in System.map, and then get an event whenever that subroutine gets called. Its pretty slick, and allows me to gather data on certain unusual events in the kernel. (I'm not using this for performance monitoring, I'm trying to do RAS).

It makes a lot of sense to me to have a generic kprobe extension, where you could give it a list of subroutine names, and it'll collect stats on the number of times that the routine was called. Some user-space thingy could poll for those stats, or you could put them in /sys or wherever.

Its more complicted than just instriumenting syscalls, but a lot more useful, I would think ...

--linas

#6 lore raw

Re: Using kprobes [was Re: [PATCH] Performance Stats: Kernel patch

Quoted 13 lines · Linas Vepstas
Quoted 4 lines · Andrew Morton

I don't think the syscall-counting feature has a future, sorry. Perhaps you could do something like hooking it up on-demand by insertion of a kprobe, dunno.

This is an interesting point. I've started fiddling with (a wrapper around) kprobes that allows me to pick any subroutine symbol in System.map, and then get an event whenever that subroutine gets called. Its pretty slick, and allows me to gather data on certain unusual events in the kernel. (I'm not using this for performance monitoring, I'm trying to do RAS).

Quoted 7 lines

It makes a lot of sense to me to have a generic kprobe extension, where you could give it a list of subroutine names, and it'll collect stats on the number of times that the routine was called. Some user-space thingy could poll for those stats, or you could put them in /sys or wherever.

Its more complicted than just instriumenting syscalls, but a lot more useful, I would think ...

Yes, this is exactly the useful kind of kprobes useage we should have in the tree.

Quoted 7 lines

--linas

_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev

---end quoted text---

#7 lore raw

Re: Using kprobes [was Re: [PATCH] Performance Stats: Kernel patch

In reply to Linas Vepstas
Quoted 15 lines · Linas Vepstas
Quoted 5 lines · Andrew Morton

I don't think the syscall-counting feature has a future, sorry. Perhaps you could do something like hooking it up on-demand by insertion of a kprobe, dunno.

This is an interesting point. I've started fiddling with (a wrapper around) kprobes that allows me to pick any subroutine symbol in System.map, and then get an event whenever that subroutine gets called. Its pretty slick, and allows me to gather data on certain unusual events in the kernel. (I'm not using this for performance monitoring, I'm trying to do RAS).

Quoted 11 lines

It makes a lot of sense to me to have a generic kprobe extension, where you could give it a list of subroutine names, and it'll collect stats on the number of times that the routine was called. Some user-space thingy
could poll for those stats, or you could put them in /sys or wherever.

Its more complicted than just instriumenting syscalls, but a lot more useful, I would think ...

--linas

Thanks Linas, but do you think that kprobes is safe for syscall counting? I think that the overhead will be much bigger in that case. In my case it is 1 line asm instruction and it is defended with #ifdefs.

Kprobes is very good thing. But is not clear for me how to count per-thread statistics. In my case I increased struct thread_info. In case with kprobes it is easy to count all do_fork execution, for example, but not for each thread. And in any case, place for keeping this counters is needed.

Maxim.

#8 lore raw
In reply to Maxim Uvarov

Hi,

Quoted 3 lines · Maxim Uvarov

Patch makes available to the user the following
task and process performance statistics:

[...]

arch/i386/kernel/entry.S sysenter_past_esp: · line 334

Quoted 9 lines
arch/i386/kernel/entry.S +1 -0
index 5e47683..26f0cc0 100644
@@ -331,6 +331,7 @@ sysenter_past_esp:
 	CFI_ADJUST_CFA_OFFSET 4
 	SAVE_ALL
 	GET_THREAD_INFO(%ebp)
+	incl	TI_syscall_count(%ebp)	# Increment syscalls counter

Other arches have this protected with #ifdef CONFIG_TASKSTATS why not here?

arch/powerpc/kernel/entry_32.S _GLOBAL(DoSyscall) · line 209

Quoted 13 lines
arch/powerpc/kernel/entry_32.S +5 -0
index c03e829..329c2f8 100644
@@ -202,6 +202,11 @@ _GLOBAL(DoSyscall)
 	bl	do_show_syscall
 #endif /* SHOW_SYSCALLS */
 	rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
+#ifdef CONFIG_THREAD_PERF_STAT_SYSC
+	lwz r11,TI_SYSC_CNT(r10)
+	addi r11,r11,1
+	stw r11,TI_SYSC_CNT(r10)
+#endif /* CONFIG_THREAD_PERF_STAT_SYSC */

Why not CONFIG_TASKSTATS, as in entry_64.S ?

Actually, grep shows that CONFIG_THREAD_PERF_STAT_SYSC is not defined anywhere.

arch/x86_64/kernel/entry.S ENTRY(system_call) · line 232

Quoted 9 lines
arch/x86_64/kernel/entry.S +1 -0
index 9f5dac6..9fd97df 100644
@@ -229,6 +229,7 @@ ENTRY(system_call)
 	movq  %rcx,RIP-ARGOFFSET(%rsp)
 	CFI_REL_OFFSET rip,RIP-ARGOFFSET
 	GET_THREAD_INFO(%rcx)
+	addq $1, threadinfo_syscall_count(%rcx)   # Increment syscalls counter

again, #ifdef CONFIG_TASKSTATS,

--linas

#9 lore raw
Quoted 14 lines · Linas Vepstas

Hi,

Quoted 4 lines · Maxim Uvarov

Patch makes available to the user the following
task and process performance statistics:

[...]

Quoted 17 lines

arch/i386/kernel/entry.S sysenter_past_esp: · line 336

Quoted 11 lines
arch/i386/kernel/entry.S +1 -0
index 5e47683..26f0cc0 100644
@@ -331,6 +331,7 @@ sysenter_past_esp:
 	CFI_ADJUST_CFA_OFFSET 4
 	SAVE_ALL
 	GET_THREAD_INFO(%ebp)
+	incl	TI_syscall_count(%ebp)	# Increment syscalls counter
 
 

Other arches have this protected with #ifdef CONFIG_TASKSTATS why not here?

Thank you. It should be protected.

Quoted 18 lines
Quoted 5 lines
arch/powerpc/kernel/entry_32.S +0 -0
index c03e829..329c2f8 100644

arch/powerpc/kernel/entry_32.S _GLOBAL(DoSyscall) · line 211

Quoted 10 lines
arch/powerpc/kernel/entry_32.S +5 -0
@@ -202,6 +202,11 @@ _GLOBAL(DoSyscall)
 	bl	do_show_syscall
 #endif /* SHOW_SYSCALLS */
 	rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
+#ifdef CONFIG_THREAD_PERF_STAT_SYSC
+	lwz r11,TI_SYSC_CNT(r10)
+	addi r11,r11,1
+	stw r11,TI_SYSC_CNT(r10)
+#endif /* CONFIG_THREAD_PERF_STAT_SYSC */
 
 

Why not CONFIG_TASKSTATS, as in entry_64.S ?

Quoted 5 lines

Actually, grep shows that CONFIG_THREAD_PERF_STAT_SYSC is not defined anywhere.

This is mistake, thank you. I have to be more considerate.

Quoted 14 lines

arch/x86_64/kernel/entry.S ENTRY(system_call) · line 234

Quoted 11 lines
arch/x86_64/kernel/entry.S +1 -0
index 9f5dac6..9fd97df 100644
@@ -229,6 +229,7 @@ ENTRY(system_call)
 	movq  %rcx,RIP-ARGOFFSET(%rsp)
 	CFI_REL_OFFSET rip,RIP-ARGOFFSET
 	GET_THREAD_INFO(%rcx)
+	addq $1, threadinfo_syscall_count(%rcx)   # Increment syscalls counter
 
 

again, #ifdef CONFIG_TASKSTATS,

Quoted 3 lines

--linas

In general I had the following idea. Defend with CONFIG_TASKSTATS all syscall increment counters in arch/*/entry.S code. It will allow to avoid this overhead if task stats interface is not supported by kernel. The overhead is too small but, it is not needed to increment counters without interface to get them.

In first version of patch I have used only /proc interface. And it is available now. So I don't really sure if defines are needed in entry.S code. I tried to do some tests and it is impossible to catch the performance difference (small overhead).

#10 lore raw
Quoted 10 lines · Maxim Uvarov
Quoted 4 lines · Linas Vepstas

Review

Quoted 1 line · Maxim Uvarov
(quoted diff) +1 -0
+	addq $1, threadinfo_syscall_count(%rcx)   # Increment syscalls 

again, #ifdef CONFIG_TASKSTATS,

So I don't really sure if defines are needed in entry.S code. I tried to do
some tests and it is impossible to catch the performance difference (small overhead).

"A penny here, and a penny there, and pretty soon it adds up to real money". Its a hot path, and its an easy fix.

--linas