[PATCH] Reduce stack usage in acct.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Attempt to reduce stack usage in acct.c (linux-2.6.12-rc1-mm3). Stack
usage was noted using checkstack.pl. Specifically:

Before patch
------------
check_free_space - 128
do_acct_process - 105

After patch
-----------
check_free_space - 36
do_acct_process - 44

Signed-off-by: Yum Rayan <[email protected]>

--- a/kernel/acct.c	2005-03-25 22:11:06.000000000 -0800
+++ b/kernel/acct.c	2005-03-30 15:33:05.000000000 -0800
@@ -103,30 +103,32 @@
  */
 static int check_free_space(struct file *file)
 {
-	struct kstatfs sbuf;
-	int res;
-	int act;
-	sector_t resume;
-	sector_t suspend;
+	struct kstatfs *sbuf = NULL;
+	int res, act;
+	sector_t resume, suspend;
 
 	spin_lock(&acct_globals.lock);
 	res = acct_globals.active;
 	if (!file || !acct_globals.needcheck)
-		goto out;
+		goto out_unlock;
 	spin_unlock(&acct_globals.lock);
 
+	sbuf = kmalloc(sizeof (struct kstatfs), GFP_KERNEL);
+	if (!sbuf)
+		goto out_res;
+
 	/* May block */
-	if (vfs_statfs(file->f_dentry->d_inode->i_sb, &sbuf))
-		return res;
-	suspend = sbuf.f_blocks * SUSPEND;
-	resume = sbuf.f_blocks * RESUME;
+	if (vfs_statfs(file->f_dentry->d_inode->i_sb, sbuf))
+		goto out_free_sbuf;
+	suspend = sbuf->f_blocks * SUSPEND;
+	resume = sbuf->f_blocks * RESUME;
 
 	sector_div(suspend, 100);
 	sector_div(resume, 100);
 
-	if (sbuf.f_bavail <= suspend)
+	if (sbuf->f_bavail <= suspend)
 		act = -1;
-	else if (sbuf.f_bavail >= resume)
+	else if (sbuf->f_bavail >= resume)
 		act = 1;
 	else
 		act = 0;
@@ -139,7 +141,7 @@
 	if (file != acct_globals.file) {
 		if (act)
 			res = act>0;
-		goto out;
+		goto out_unlock;
 	}
 
 	if (acct_globals.active) {
@@ -159,8 +161,11 @@
 	acct_globals.timer.expires = jiffies + ACCT_TIMEOUT*HZ;
 	add_timer(&acct_globals.timer);
 	res = acct_globals.active;
-out:
+out_unlock:
 	spin_unlock(&acct_globals.lock);
+out_free_sbuf:
+	kfree(sbuf);
+out_res:
 	return res;
 }
 
@@ -380,7 +385,7 @@
  */
 static void do_acct_process(long exitcode, struct file *file)
 {
-	acct_t ac;
+	acct_t *ac;
 	mm_segment_t fs;
 	unsigned long vsize;
 	unsigned long flim;
@@ -395,14 +400,18 @@
 	if (!check_free_space(file))
 		return;
 
+	ac = kmalloc(sizeof (acct_t), GFP_KERNEL);
+	if (!ac)
+		return;
+
 	/*
 	 * Fill the accounting struct with the needed info as recorded
 	 * by the different kernel functions.
 	 */
-	memset((caddr_t)&ac, 0, sizeof(acct_t));
+	memset(ac, 0, sizeof(acct_t));
 
-	ac.ac_version = ACCT_VERSION | ACCT_BYTEORDER;
-	strlcpy(ac.ac_comm, current->comm, sizeof(ac.ac_comm));
+	ac->ac_version = ACCT_VERSION | ACCT_BYTEORDER;
+	strlcpy(ac->ac_comm, current->comm, sizeof(ac->ac_comm));
 
 	/* calculate run_time in nsec*/
 	do_posix_clock_monotonic_gettime(&uptime);
@@ -412,57 +421,57 @@
 	/* convert nsec -> AHZ */
 	elapsed = nsec_to_AHZ(run_time);
 #if ACCT_VERSION==3
-	ac.ac_etime = encode_float(elapsed);
+	ac->ac_etime = encode_float(elapsed);
 #else
-	ac.ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ?
+	ac->ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ?
 	                       (unsigned long) elapsed : (unsigned long) -1l);
 #endif
 #if ACCT_VERSION==1 || ACCT_VERSION==2
 	{
 		/* new enlarged etime field */
 		comp2_t etime = encode_comp2_t(elapsed);
-		ac.ac_etime_hi = etime >> 16;
-		ac.ac_etime_lo = (u16) etime;
+		ac->ac_etime_hi = etime >> 16;
+		ac->ac_etime_lo = (u16) etime;
 	}
 #endif
 	do_div(elapsed, AHZ);
-	ac.ac_btime = xtime.tv_sec - elapsed;
-	ac.ac_utime = encode_comp_t(jiffies_to_AHZ(
+	ac->ac_btime = xtime.tv_sec - elapsed;
+	ac->ac_utime = encode_comp_t(jiffies_to_AHZ(
 					    current->signal->utime +
 					    current->group_leader->utime));
-	ac.ac_stime = encode_comp_t(jiffies_to_AHZ(
+	ac->ac_stime = encode_comp_t(jiffies_to_AHZ(
 					    current->signal->stime +
 					    current->group_leader->stime));
 	/* we really need to bite the bullet and change layout */
-	ac.ac_uid = current->uid;
-	ac.ac_gid = current->gid;
+	ac->ac_uid = current->uid;
+	ac->ac_gid = current->gid;
 #if ACCT_VERSION==2
-	ac.ac_ahz = AHZ;
+	ac->ac_ahz = AHZ;
 #endif
 #if ACCT_VERSION==1 || ACCT_VERSION==2
 	/* backward-compatible 16 bit fields */
-	ac.ac_uid16 = current->uid;
-	ac.ac_gid16 = current->gid;
+	ac->ac_uid16 = current->uid;
+	ac->ac_gid16 = current->gid;
 #endif
 #if ACCT_VERSION==3
-	ac.ac_pid = current->tgid;
-	ac.ac_ppid = current->parent->tgid;
+	ac->ac_pid = current->tgid;
+	ac->ac_ppid = current->parent->tgid;
 #endif
 
 	read_lock(&tasklist_lock);	/* pin current->signal */
-	ac.ac_tty = current->signal->tty ?
+	ac->ac_tty = current->signal->tty ?
 		old_encode_dev(tty_devnum(current->signal->tty)) : 0;
 	read_unlock(&tasklist_lock);
 
-	ac.ac_flag = 0;
+	ac->ac_flag = 0;
 	if (current->flags & PF_FORKNOEXEC)
-		ac.ac_flag |= AFORK;
+		ac->ac_flag |= AFORK;
 	if (current->flags & PF_SUPERPRIV)
-		ac.ac_flag |= ASU;
+		ac->ac_flag |= ASU;
 	if (current->flags & PF_DUMPCORE)
-		ac.ac_flag |= ACORE;
+		ac->ac_flag |= ACORE;
 	if (current->flags & PF_SIGNALED)
-		ac.ac_flag |= AXSIG;
+		ac->ac_flag |= AXSIG;
 
 	vsize = 0;
 	if (current->mm) {
@@ -476,15 +485,15 @@
 		up_read(&current->mm->mmap_sem);
 	}
 	vsize = vsize / 1024;
-	ac.ac_mem = encode_comp_t(vsize);
-	ac.ac_io = encode_comp_t(0 /* current->io_usage */);	/* %% */
-	ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
-	ac.ac_minflt = encode_comp_t(current->signal->min_flt +
+	ac->ac_mem = encode_comp_t(vsize);
+	ac->ac_io = encode_comp_t(0 /* current->io_usage */);	/* %% */
+	ac->ac_rw = encode_comp_t(ac->ac_io / 1024);
+	ac->ac_minflt = encode_comp_t(current->signal->min_flt +
 				     current->group_leader->min_flt);
-	ac.ac_majflt = encode_comp_t(current->signal->maj_flt +
+	ac->ac_majflt = encode_comp_t(current->signal->maj_flt +
 				     current->group_leader->maj_flt);
-	ac.ac_swaps = encode_comp_t(0);
-	ac.ac_exitcode = exitcode;
+	ac->ac_swaps = encode_comp_t(0);
+	ac->ac_exitcode = exitcode;
 
 	/*
          * Kernel segment override to datasegment and write it
@@ -497,10 +506,11 @@
  	 */
 	flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
 	current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
-	file->f_op->write(file, (char *)&ac,
+	file->f_op->write(file, (char *)ac,
 			       sizeof(acct_t), &file->f_pos);
 	current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
 	set_fs(fs);
+	kfree(ac);
 }
 
 /*
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux