All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matt Mackall <mpm@selenic.com>
To: Andi Kleen <andi@firstfloor.org>, Pavel Machek <pavel@suse.cz>,
	Ingo Molnar <mingo@elte.hu>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [RFC PATCH 1/2] Shrink compat_ioctl.c
Date: Mon, 29 Sep 2008 18:27:10 -0500	[thread overview]
Message-ID: <1222730830.23159.12.camel@calx> (raw)

I'm throwing this out untested as I don't have a mixed 64/32 system
handy at the moment.

compat_ioctl: shrink structures

Initially, compat_ioctl.c has a ~18k table of translated ioctls.
Each table entry is 24 bytes but we can shrink this to 16:

- use short table indexes rather than a pointer for .next values
- use unsigned ints for cmd numbers (they're 32-bit ioctls, after all)

In addition, there's a 2k hash table that we can do away with simply
by hashifying the main table in place at init time.

This saves about 6k data and 2k BSS.

diff -r f6d1daaf90b2 -r b055e64aea17 fs/compat_ioctl.c
--- a/fs/compat_ioctl.c	Mon Sep 29 17:28:28 2008 -0500
+++ b/fs/compat_ioctl.c	Mon Sep 29 17:28:41 2008 -0500
@@ -1825,21 +1825,21 @@
 					unsigned long, struct file *);
 
 struct ioctl_trans {
-	unsigned long cmd;
 	ioctl_trans_handler_t handler;
-	struct ioctl_trans *next;
+	unsigned int cmd;
+	unsigned short next;
 };
 
 #define HANDLE_IOCTL(cmd,handler) \
-	{ (cmd), (ioctl_trans_handler_t)(handler) },
+	{ (ioctl_trans_handler_t)(handler), (cmd)},
 
 /* pointer to compatible structure or no argument */
 #define COMPATIBLE_IOCTL(cmd) \
-	{ (cmd), do_ioctl32_pointer },
+	{ do_ioctl32_pointer, (cmd) },
 
 /* argument is an unsigned long integer, not a pointer */
 #define ULONG_IOCTL(cmd) \
-	{ (cmd), (ioctl_trans_handler_t)sys_ioctl },
+	{ (ioctl_trans_handler_t)sys_ioctl, (cmd) },
 
 /* ioctl should not be warned about even if it's not implemented.
    Valid reasons to use this:
@@ -1850,7 +1850,7 @@
    Most other reasons are not valid. */
 #define IGNORE_IOCTL(cmd) COMPATIBLE_IOCTL(cmd)
 
-static struct ioctl_trans ioctl_start[] = {
+static struct ioctl_trans ioctl_table[] = {
 /* compatible ioctls first */
 COMPATIBLE_IOCTL(0x4B50)   /* KDGHWCLK - not in the kernel, but don't complain */
 COMPATIBLE_IOCTL(0x4B51)   /* KDSHWCLK - not in the kernel, but don't complain */
@@ -2728,10 +2728,9 @@
 #endif
 };
 
-#define IOCTL_HASHSIZE 256
-static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
+#define IOCTL_HASHSIZE 256 /* must be less than table size */
 
-static inline unsigned long ioctl32_hash(unsigned long cmd)
+static inline unsigned int ioctl32_hash(unsigned int cmd)
 {
 	return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE;
 }
@@ -2770,7 +2769,7 @@
 {
 	struct file *filp;
 	int error = -EBADF;
-	struct ioctl_trans *t;
+	int t;
 	int fput_needed;
 
 	filp = fget_light(fd, &fput_needed);
@@ -2815,8 +2814,8 @@
 		break;
 	}
 
-	for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) {
-		if (t->cmd == cmd)
+	for (t = ioctl32_hash(cmd); t >= 0; t = ioctl_table[t].next) {
+		if (ioctl_table[t].cmd == cmd)
 			goto found_handler;
 	}
 
@@ -2837,9 +2836,9 @@
 	goto out_fput;
 
  found_handler:
-	if (t->handler) {
+	if (ioctl_table[t].handler) {
 		lock_kernel();
-		error = t->handler(fd, cmd, arg, filp);
+		error = ioctl_table[t].handler(fd, cmd, arg, filp);
 		unlock_kernel();
 		goto out_fput;
 	}
@@ -2852,34 +2851,25 @@
 	return error;
 }
 
-static void ioctl32_insert_translation(struct ioctl_trans *trans)
-{
-	unsigned long hash;
-	struct ioctl_trans *t;
-
-	hash = ioctl32_hash (trans->cmd);
-	if (!ioctl32_hash_table[hash])
-		ioctl32_hash_table[hash] = trans;
-	else {
-		t = ioctl32_hash_table[hash];
-		while (t->next)
-			t = t->next;
-		trans->next = NULL;
-		t->next = trans;
-	}
-}
-
 static int __init init_sys32_ioctl(void)
 {
 	int i;
+	unsigned long hash;
+	struct ioctl_trans t;
 
-	for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) {
-		if (ioctl_start[i].next) {
-			printk("ioctl translation %d bad\n",i);
-			return -1;
-		}
+	/* hash-order table in-place */
+	for (i = 0; i < ARRAY_SIZE(ioctl_table); i++) {
+		hash = ioctl32_hash(ioctl_table[i].cmd);
+		t = ioctl_table[hash];
+		ioctl_table[hash] = ioctl_table[i];
+		ioctl_table[i] = t;
+	}
 
-		ioctl32_insert_translation(&ioctl_start[i]);
+	/* link entries outside of hash area */
+	for (i = IOCTL_HASHSIZE; i < ARRAY_SIZE(ioctl_table); i++) {
+		hash = ioctl32_hash(ioctl_table[i].cmd);
+		ioctl_table[i].next = ioctl_table[hash].next;
+		ioctl_table[hash].next = i;
 	}
 	return 0;
 }


-- 
Mathematics is the supreme nostalgia of our time.


             reply	other threads:[~2008-09-29 23:29 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-29 23:27 Matt Mackall [this message]
2008-09-29 23:29 ` [RFC PATCH 2/2] Shrink compat_ioctl.c Matt Mackall
2008-09-29 23:38 ` [RFC PATCH 1/2] " Andi Kleen
2008-09-29 23:38   ` Matt Mackall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1222730830.23159.12.camel@calx \
    --to=mpm@selenic.com \
    --cc=andi@firstfloor.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=pavel@suse.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.