All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] add dispatch_i8259_irq() to i8259.c
From: Ralf Baechle @ 2002-12-17 18:23 UTC (permalink / raw)
  To: Dominic Sweetman; +Cc: Maciej W. Rozycki, Jun Sun, linux-mips
In-Reply-To: <15871.13866.515311.16388@arsenal.algor.co.uk>

On Tue, Dec 17, 2002 at 02:35:22PM +0000, Dominic Sweetman wrote:

> Alternatively, many MIPS systems have a hardware feature which enables
> them to generate imitation-x86 interrupt acknowledge cycles, so you
> can keep the 8259s in complete ignorance that they're not being
> controlled by an x86.  

Unless the hardware is an RM200 where under special circumstances the
hardware acknowledge feature may result in loss of some or all i8259
interrupts until full-reinitialization of the i8259 ...

Bugs, bugs ...

  Ralf

^ permalink raw reply

* Re: Intel P6 vs P7 system call performance
From: Ulrich Drepper @ 2002-12-17 18:30 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Matti Aarnio, Hugh Dickins, Dave Jones, Ingo Molnar, linux-kernel,
	hpa
In-Reply-To: <Pine.LNX.4.44.0212170948380.2702-100000@home.transmeta.com>

Linus Torvalds wrote:

> Uli, how about I just add one ne warchitecture-specific ELF AT flag, which
> is the "base of sysinfo page". Right now that page is all zeroes except
> for the system call trampoline at the beginning, but we might want to add
> other system information to the page in the future (it is readable, after
> all).
> 
> So we'd have an AT_SYSINFO entry, that with the current implementation
> would just get the value 0xfffff000. And then the glibc startup code could
> easily be backwards compatible with the suggestion I had in the previous
> email. Since we basically want to do an indirect jump anyway (because of
> the lack of absolute jumps in the instruction set), this looks like the
> natural way to do it.

Yes, I definitely think that a new AT_* value is at order and it's a
nice way to determine the address.

But it will eliminate the problem.  Remember: the x86 (unlike x86-64)
has no PC-relative data addressing mode.  I.e., in a DSO to find a
memory location with an address I need a base register which isn't
available anymore at the time the call is made.

You have to assume that all the registers, including %ebp, are used at
the time of the call.  This makes it impossible to find a memory
location in a DSO without text relocation (i.e., making parts of the
code writable, at least for a moment).  This is time consuming and not
resource friendly.

There is one way around this and maybe it is what should be done: we
have the TLS memory available.  And since this vsyscall stuff gets
introduced after the TLS is functional it is a possibility.

The address received in AT_SYSINFO is stored in a word in the TCB
(thread control block).  Then the code to call through this is a variant
of what I posted earlier

  movl $__NR_##name, %eax
  call *%gs:-__NR_##name+TCB_OFFSET(%eax)

In case the vsyscall stuff is not available we jump to something like

   int $0x80
   ret

The address of this code is the default value of the TCB word.


There is another thing we might want to consider.  The above code jump
to 0xfffff000 or whatever adddres is specified.  I.e., the
demultiplexing happens in the kernel.  Do we want to do this at
userlevel?  This would allow almost no-cost determination of those
syscalls which can be handled at userlevel (getpid, getppid, ...).

-- 
--------------.                        ,-.            444 Castro Street
Ulrich Drepper \    ,-----------------'   \ Mountain View, CA 94041 USA
Red Hat         `--' drepper at redhat.com `---------------------------


^ permalink raw reply

* Re: [parisc-linux] quad tulip now not functional in 2.4.20
From: Grant Grundler @ 2002-12-17 18:19 UTC (permalink / raw)
  To: jsoe0708; +Cc: Ed Schaller, parisc-linux
In-Reply-To: <3DED9BBD000022D4@ocpmta7.freegates.net>

On Tue, Dec 17, 2002 at 04:14:10PM +0100, jsoe0708@tiscali.be wrote:
> >I will try to revert tulip driver and advise you.
> Well I find some minutes to do this reverse and it works.
> Still have to find the bug ?

Unfortunately yes.
But since the diff is small, it's alot easier.

I'm most suspicious about the added checks for length field in eeprom.
But I'll review the diff again and tinker with it today or tomorrow.
I added that thinking that code only gets executed when there is no
phy table (eg built-in). But the add-on cards do have a phy table.

grant

^ permalink raw reply

* Re: big load
From: Milan Roubal @ 2002-12-17 18:24 UTC (permalink / raw)
  To: Joseph D. Wagner, linux-kernel
In-Reply-To: <000801c2a598$99eccc00$35251c43@joe>

Hi,
now in clean system there are these values, I don't have got these values
from that fault.
# vmstat
   procs                      memory    swap          io     system
cpu
 r  b  w   swpd   free   buff  cache  si  so    bi    bo   in    cs  us  sy
id
 0  0  0      0  19924   1488 747392   0   0    93    87  138   136   2   2
96

Thanx
    Milan

----- Original Message -----
From: "Joseph D. Wagner" <wagnerjd@prodigy.net>
To: "'Milan Roubal'" <roubal@jobatlas.cz>; <linux-kernel@vger.kernel.org>
Sent: Tuesday, December 17, 2002 7:50 AM
Subject: RE: big load


I remember an error like this from a few months ago.  Are you encountering
large I/O access?  Lots of swapping?  Lots of buffer input?  Lots of buffer
output?  This would show up on vmstats.

Joseph Wagner

-----Original Message-----
From: linux-kernel-owner@vger.kernel.org
[mailto:linux-kernel-owner@vger.kernel.org] On Behalf Of Milan Roubal
Sent: Sunday, December 15, 2002 7:55 PM
To: linux-kernel@vger.kernel.org
Subject: big load

Hi,
I have got server runnig 5 days and now its doing this:

2:48am  up 5 days, 11:23,  2 users,  load average: 19.97, 15.70, 10.63
61 processes: 60 sleeping, 1 running, 0 zombie, 0 stopped
CPU0 states:  0.0% user,  8.1% system,  0.0% nice, 91.4% idle
CPU1 states:  0.0% user,  0.1% system,  0.0% nice, 99.4% idle

I can't understand where I can got so big load
processor is idle all the time, but load is going higher and higher.

  2:50am  up 5 days, 11:24,  2 users,  load average: 21.45, 17.45, 11.80
62 processes: 61 sleeping, 1 running, 0 zombie, 0 stopped
CPU0 states:  0.0% user,  0.0% system,  0.0% nice, 100.0% idle
CPU1 states:  0.0% user,  0.1% system,  0.0% nice, 99.4% idle

my process:


  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
13782 root      13   0   892  892   696 R     0.2  0.0   0:00 top
    1 root      20   0    84   84    52 S     0.0  0.0   0:11 init
    2 root      20   0     0    0     0 SW    0.0  0.0   0:00 keventd
    3 root      20  19     0    0     0 SWN   0.0  0.0   0:03 ksoftirqd_CPU0
    4 root      20  19     0    0     0 SWN   0.0  0.0   0:00 ksoftirqd_CPU1
    5 root      20   0     0    0     0 SW    0.0  0.0  17:22 kswapd
    6 root       0   0     0    0     0 SW    0.0  0.0   1:45 bdflush
    7 root      20   0     0    0     0 SW    0.0  0.0  33:48 kupdated
    8 root      20   0     0    0     0 SW    0.0  0.0   0:00 kinoded
   11 root       0 -20     0    0     0 SW<   0.0  0.0   0:00 mdrecoveryd
   14 root      20   0     0    0     0 SW    0.0  0.0   0:03 kreiserfsd
   51 root      20 -20     0    0     0 SW<   0.0  0.0  11:20 raid5d
  245 root      20   0     0    0     0 DW    0.0  0.0   0:09 pagebuf_daemon
  388 root      20   0   316  316   208 S     0.0  0.0   0:00 syslogd
  391 root      20   0   440  440   216 S     0.0  0.0   0:00 klogd
  427 root      20   0     0    0     0 SW    0.0  0.0   0:00 khubd

What could be wrong?
In log is only this message:

Dec 16 02:32:37 fileserver kernel: lease timed out

# /usr/local/samba/bin/smbd -V
Version 2.2.6

System is 2.4.18-3 from SuSE,
SuSE 8.1 distribution.
Filesystem XFS on 1TB RAID5 array
    Thanx
    Milan Roubal


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/




^ permalink raw reply

* [PATCH] Support for NFSv4 READ + WRITE attribute cache consistency
From: Trond Myklebust @ 2002-12-17 18:16 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: NFS maillist


Retrieve the post-operation attribute changes for NFSv4 READ and
WRITE operations. Unlike for NFSv2 and NFSv3, we do not retrieve the
full set of file attributes. The main reason for this is that
interpreting attributes is a much heavier task on NFSv4 (requiring, for
instance, translation of file owner names into uids ...). Hence

  For a READ request, we retrieve only the 'change attribute' (for cache
  consistency checking) and the atime.

  For a WRITE request, we retrieve the 'change attribute' and the file size.
  In addition, we retrieve the value of the change attribute prior to the
  write operation, in order to be able to do weak cache consistency checking.

Cheers,
  Trond

diff -u --recursive --new-file linux-2.5.52-02-nfsv4_write/fs/nfs/nfs3proc.c linux-2.5.52-03-nfsv4_attr/fs/nfs/nfs3proc.c
--- linux-2.5.52-02-nfsv4_write/fs/nfs/nfs3proc.c	2002-12-17 15:27:47.000000000 +0100
+++ linux-2.5.52-03-nfsv4_attr/fs/nfs/nfs3proc.c	2002-12-17 15:28:07.000000000 +0100
@@ -67,6 +67,20 @@
 	return 1;
 }
 
+static void
+nfs3_write_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
+{
+	if (fattr->valid & NFS_ATTR_FATTR) {
+		if (!(fattr->valid & NFS_ATTR_WCC)) {
+			fattr->pre_size  = NFS_CACHE_ISIZE(inode);
+			fattr->pre_mtime = NFS_CACHE_MTIME(inode);
+			fattr->pre_ctime = NFS_CACHE_CTIME(inode);
+			fattr->valid |= NFS_ATTR_WCC;
+		}
+		nfs_refresh_inode(inode, fattr);
+	}
+}
+
 /*
  * Bare-bones access to getattr: this is for nfs_read_super.
  */
@@ -239,6 +253,8 @@
 	dprintk("NFS call  read %d @ %Ld\n", count, (long long)offset);
 	fattr->valid = 0;
 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
+	if (status >= 0)
+		nfs_refresh_inode(inode, fattr);
 	dprintk("NFS reply read: %d\n", status);
 	*eofp = res.eof;
 	return status;
@@ -279,6 +295,9 @@
 
 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
 
+	if (status >= 0)
+		nfs3_write_refresh_inode(inode, fattr);
+
 	dprintk("NFS reply read: %d\n", status);
 	return status < 0? status : res.count;
 }
@@ -685,9 +704,13 @@
 static void
 nfs3_read_done(struct rpc_task *task)
 {
+	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+
 	if (nfs3_async_handle_jukebox(task))
 		return;
 	/* Call back common NFS readpage processing */
+	if (task->tk_status >= 0)
+		nfs_refresh_inode(data->inode, &data->fattr);
 	nfs_readpage_result(task);
 }
 
@@ -730,8 +753,12 @@
 static void
 nfs3_write_done(struct rpc_task *task)
 {
+	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+
 	if (nfs3_async_handle_jukebox(task))
 		return;
+	if (task->tk_status >= 0)
+		nfs3_write_refresh_inode(data->inode, data->res.fattr);
 	nfs_writeback_done(task);
 }
 
@@ -784,8 +811,12 @@
 static void
 nfs3_commit_done(struct rpc_task *task)
 {
+	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+
 	if (nfs3_async_handle_jukebox(task))
 		return;
+	if (task->tk_status >= 0)
+		nfs3_write_refresh_inode(data->inode, data->res.fattr);
 	nfs_commit_done(task);
 }
 
diff -u --recursive --new-file linux-2.5.52-02-nfsv4_write/fs/nfs/nfs4proc.c linux-2.5.52-03-nfsv4_attr/fs/nfs/nfs4proc.c
--- linux-2.5.52-02-nfsv4_write/fs/nfs/nfs4proc.c	2002-12-17 15:27:47.000000000 +0100
+++ linux-2.5.52-03-nfsv4_attr/fs/nfs/nfs4proc.c	2002-12-17 15:28:07.000000000 +0100
@@ -980,8 +980,12 @@
 	dprintk("NFS call  read %d @ %Ld\n", count, (long long)offset);
 	fattr->valid = 0;
 	status = rpc_call_sync(server->client, &msg, flags);
-	if (!status)
+	if (!status) {
 		renew_lease(server, timestamp);
+		/* Check cache consistency */
+		if (fattr->change_attr != NFS_CHANGE_ATTR(inode))
+			nfs_zap_caches(inode);
+	}
 	dprintk("NFS reply read: %d\n", status);
 	*eofp = res.eof;
 	return status;
@@ -1338,9 +1342,16 @@
 nfs4_read_done(struct rpc_task *task)
 {
 	struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
+	struct inode *inode = data->inode;
+	struct nfs_fattr *fattr = data->res.fattr;
 
 	if (task->tk_status > 0)
-		renew_lease(NFS_SERVER(data->inode), data->timestamp);
+		renew_lease(NFS_SERVER(inode), data->timestamp);
+	/* Check cache consistency */
+	if (fattr->change_attr != NFS_CHANGE_ATTR(inode))
+		nfs_zap_caches(inode);
+	if (fattr->bitmap[1] & FATTR4_WORD1_TIME_ACCESS)
+		inode->i_atime = fattr->atime;
 	/* Call back common NFS readpage processing */
 	nfs_readpage_result(task);
 }
@@ -1382,12 +1393,29 @@
 }
 
 static void
+nfs4_write_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
+{
+	/* Check cache consistency */
+	if (fattr->pre_change_attr != NFS_CHANGE_ATTR(inode))
+		nfs_zap_caches(inode);
+	NFS_CHANGE_ATTR(inode) = fattr->change_attr;
+	if (fattr->bitmap[1] & FATTR4_WORD1_SPACE_USED)
+		inode->i_blocks = (fattr->du.nfs3.used + 511) >> 9;
+	if (fattr->bitmap[1] & FATTR4_WORD1_TIME_METADATA)
+		inode->i_ctime = fattr->ctime;
+	if (fattr->bitmap[1] & FATTR4_WORD1_TIME_MODIFY)
+		inode->i_mtime = fattr->mtime;
+}
+
+static void
 nfs4_write_done(struct rpc_task *task)
 {
 	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+	struct inode *inode = data->inode;
 	
-	if (task->tk_status > 0)
-		renew_lease(NFS_SERVER(data->inode), data->timestamp);
+	if (task->tk_status >= 0)
+		renew_lease(NFS_SERVER(inode), data->timestamp);
+	nfs4_write_refresh_inode(inode, data->res.fattr);
 	/* Call back common NFS writeback processing */
 	nfs_writeback_done(task);
 }
@@ -1439,6 +1467,16 @@
 }
 
 static void
+nfs4_commit_done(struct rpc_task *task)
+{
+	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+	
+	nfs4_write_refresh_inode(data->inode, data->res.fattr);
+	/* Call back common NFS writeback processing */
+	nfs_commit_done(task);
+}
+
+static void
 nfs4_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how)
 {
 	struct rpc_task	*task = &data->task;
@@ -1462,7 +1500,7 @@
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs_commit_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), nfs4_commit_done, flags);
 	task->tk_calldata = data;
 	/* Release requests */
 	task->tk_release = nfs_commit_release;
diff -u --recursive --new-file linux-2.5.52-02-nfsv4_write/fs/nfs/nfs4xdr.c linux-2.5.52-03-nfsv4_attr/fs/nfs/nfs4xdr.c
--- linux-2.5.52-02-nfsv4_write/fs/nfs/nfs4xdr.c	2002-12-17 15:27:47.000000000 +0100
+++ linux-2.5.52-03-nfsv4_attr/fs/nfs/nfs4xdr.c	2002-12-17 15:28:07.000000000 +0100
@@ -78,27 +78,43 @@
 #define encode_putfh_maxsz	op_encode_hdr_maxsz + 1 + \
 				(NFS4_FHSIZE >> 2)
 #define decode_putfh_maxsz	op_decode_hdr_maxsz
+#define encode_read_getattr_maxsz	op_encode_hdr_maxsz + 2
+#define decode_read_getattr_maxsz	op_decode_hdr_maxsz + 8
+#define encode_pre_write_getattr_maxsz	op_encode_hdr_maxsz + 2
+#define decode_pre_write_getattr_maxsz	op_decode_hdr_maxsz + 5
+#define encode_post_write_getattr_maxsz	op_encode_hdr_maxsz + 2
+#define decode_post_write_getattr_maxsz	op_decode_hdr_maxsz + 13
 
 #define NFS4_enc_compound_sz	1024  /* XXX: large enough? */
 #define NFS4_dec_compound_sz	1024  /* XXX: large enough? */
 #define NFS4_enc_read_sz	compound_encode_hdr_maxsz + \
 				encode_putfh_maxsz + \
+				encode_read_getattr_maxsz + \
 				op_encode_hdr_maxsz + 7
 #define NFS4_dec_read_sz	compound_decode_hdr_maxsz + \
 				decode_putfh_maxsz + \
+				decode_read_getattr_maxsz + \
 				op_decode_hdr_maxsz + 2
 #define NFS4_enc_write_sz	compound_encode_hdr_maxsz + \
 				encode_putfh_maxsz + \
-				op_encode_hdr_maxsz + 8
+				encode_pre_write_getattr_maxsz + \
+				op_encode_hdr_maxsz + 8 + \
+				encode_post_write_getattr_maxsz
 #define NFS4_dec_write_sz	compound_decode_hdr_maxsz + \
 				decode_putfh_maxsz + \
-				op_decode_hdr_maxsz + 4
+				decode_pre_write_getattr_maxsz + \
+				op_decode_hdr_maxsz + 4 + \
+				decode_post_write_getattr_maxsz
 #define NFS4_enc_commit_sz	compound_encode_hdr_maxsz + \
 				encode_putfh_maxsz + \
-				op_encode_hdr_maxsz + 3
+				encode_pre_write_getattr_maxsz + \
+				op_encode_hdr_maxsz + 3 + \
+				encode_post_write_getattr_maxsz
 #define NFS4_dec_commit_sz	compound_decode_hdr_maxsz + \
 				decode_putfh_maxsz + \
-				op_decode_hdr_maxsz + 2
+				decode_pre_write_getattr_maxsz + \
+				op_decode_hdr_maxsz + 2 + \
+				decode_post_write_getattr_maxsz
 
 
 static struct {
@@ -391,19 +407,69 @@
 }
 
 static int
-encode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr)
+encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap)
+{
+        uint32_t *p;
+
+        RESERVE_SPACE(12);
+        WRITE32(OP_GETATTR);
+        WRITE32(1);
+        WRITE32(bitmap);
+        return 0;
+}
+
+static int
+encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1)
 {
         uint32_t *p;
 
         RESERVE_SPACE(16);
         WRITE32(OP_GETATTR);
         WRITE32(2);
-        WRITE32(getattr->gt_bmval[0]);
-        WRITE32(getattr->gt_bmval[1]);
-
+        WRITE32(bm0);
+        WRITE32(bm1);
         return 0;
 }
 
+static inline int
+encode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr)
+{
+	return encode_getattr_two(xdr, getattr->gt_bmval[0],
+					getattr->gt_bmval[1]);
+}
+
+/*
+ * Request the change attribute in order to check attribute+cache consistency
+ */
+static inline int
+encode_read_getattr(struct xdr_stream *xdr)
+{
+	return encode_getattr_two(xdr, FATTR4_WORD0_CHANGE,
+			FATTR4_WORD1_TIME_ACCESS);
+}
+
+/*
+ * Request the change attribute prior to doing a write operation
+ */
+static inline int
+encode_pre_write_getattr(struct xdr_stream *xdr)
+{
+	/* Request the change attribute */
+	return encode_getattr_one(xdr, FATTR4_WORD0_CHANGE);
+}
+
+/*
+ * Request the change attribute, size, and [cm]time after a write operation
+ */
+static inline int
+encode_post_write_getattr(struct xdr_stream *xdr)
+{
+	return encode_getattr_two(xdr, FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE,
+			FATTR4_WORD1_SPACE_USED |
+			FATTR4_WORD1_TIME_METADATA |
+			FATTR4_WORD1_TIME_MODIFY);
+}
+
 static int
 encode_getfh(struct xdr_stream *xdr)
 {
@@ -853,7 +919,7 @@
 	struct rpc_auth	*auth = req->rq_task->tk_auth;
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
-		.nops	= 2,
+		.nops	= 3,
 	};
 	int replen, status;
 
@@ -863,12 +929,16 @@
 	if (status)
 		goto out;
 	status = encode_read(&xdr, args);
+	if (status)
+		goto out;
+	status = encode_read_getattr(&xdr);
 
 	/* set up reply iovec
 	 *    toplevel status + taglen=0 + rescount + OP_PUTFH + status
 	 *       + OP_READ + status + eof + datalen = 9
 	 */
-	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2;
+	replen = (RPC_REPHDRSIZE + auth->au_rslack +
+			NFS4_dec_read_sz - decode_read_getattr_maxsz) << 2;
 	xdr_inline_pages(&req->rq_rcv_buf, replen,
 			 args->pages, args->pgbase, args->count);
 out:
@@ -883,7 +953,7 @@
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
-		.nops   = 2,
+		.nops   = 4,
 	};
 	int status;
 
@@ -892,7 +962,13 @@
 	status = encode_putfh(&xdr, args->fh);
 	if (status)
 		goto out;
+	status = encode_pre_write_getattr(&xdr);
+	if (status)
+		goto out;
 	status = encode_write(&xdr, args);
+	if (status)
+		goto out;
+	status = encode_post_write_getattr(&xdr);
 out:
 	return status;
 }
@@ -905,7 +981,7 @@
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
-		.nops   = 2,
+		.nops   = 4,
 	};
 	int status;
 
@@ -914,7 +990,13 @@
 	status = encode_putfh(&xdr, args->fh);
 	if (status)
 		goto out;
+	status = encode_pre_write_getattr(&xdr);
+	if (status)
+		goto out;
 	status = encode_commit(&xdr, args);
+	if (status)
+		goto out;
+	status = encode_post_write_getattr(&xdr);
 out:
 	return status;
 }
@@ -1360,6 +1442,139 @@
 }
 
 static int
+decode_change_attr(struct xdr_stream *xdr, uint64_t *change_attr)
+{
+	uint32_t *p;
+	uint32_t attrlen, bmlen, bmval = 0;
+	int status;
+
+	status = decode_op_hdr(xdr, OP_GETATTR);
+	if (status)
+		return status;
+	READ_BUF(4);
+	READ32(bmlen);
+	if (bmlen < 1)
+		return -EIO;
+	READ_BUF(bmlen << 2);
+	READ32(bmval);
+	if (bmval != FATTR4_WORD0_CHANGE) {
+		printk(KERN_NOTICE "decode_change_attr: server returned bad attribute bitmap 0x%x\n",
+			(unsigned int)bmval);
+		return -EIO;
+	}
+	READ_BUF(4);
+	READ32(attrlen);
+	READ_BUF(attrlen);
+	if (attrlen < 8) {
+		printk(KERN_NOTICE "decode_change_attr: server returned bad attribute length %u\n",
+				(unsigned int)attrlen);
+		return -EIO;
+	}
+	READ64(*change_attr);
+	return 0;
+}
+
+static int
+decode_read_getattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
+{
+	uint32_t *p;
+	uint32_t attrlen, bmlen, bmval0 = 0, bmval1 = 0;
+	int status;
+
+	status = decode_op_hdr(xdr, OP_GETATTR);
+	if (status)
+		return status;
+	READ_BUF(4);
+	READ32(bmlen);
+	if (bmlen < 1)
+		return -EIO;
+	READ_BUF(bmlen << 2);
+	READ32(bmval0);
+	if (bmval0 != FATTR4_WORD0_CHANGE)
+		goto out_bad_bitmap;
+	if (bmlen > 1) {
+		READ32(bmval1);
+		if (bmval1 & ~(FATTR4_WORD1_TIME_ACCESS))
+			goto out_bad_bitmap;
+	}
+	READ_BUF(4);
+	READ32(attrlen);
+	READ_BUF(attrlen);
+	if (attrlen < 16) {
+		printk(KERN_NOTICE "decode_post_write_getattr: server returned bad attribute length %u\n",
+				(unsigned int)attrlen);
+		return -EIO;
+	}
+	READ64(fattr->change_attr);
+	if (bmval1 & FATTR4_WORD1_TIME_ACCESS)
+		READTIME(fattr->atime);
+	fattr->bitmap[0] = bmval0;
+	fattr->bitmap[1] = bmval1;
+	return 0;
+out_bad_bitmap:
+	printk(KERN_NOTICE "decode_read_getattr: server returned bad attribute bitmap 0x%x/0x%x\n",
+			(unsigned int)bmval0, (unsigned int)bmval1);
+	return -EIO;
+}
+
+static int
+decode_pre_write_getattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
+{
+	return decode_change_attr(xdr, &fattr->pre_change_attr);
+}
+
+static int
+decode_post_write_getattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
+{
+	uint32_t *p;
+	uint32_t attrlen, bmlen, bmval0 = 0, bmval1 = 0;
+	int status;
+
+	status = decode_op_hdr(xdr, OP_GETATTR);
+	if (status)
+		return status;
+	READ_BUF(4);
+	READ32(bmlen);
+	if (bmlen < 1)
+		return -EIO;
+	READ_BUF(bmlen << 2);
+	READ32(bmval0);
+	if (bmval0 != (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE))
+		goto out_bad_bitmap;
+	if (bmlen > 1) {
+		READ32(bmval1);
+		if (bmval1 & ~(FATTR4_WORD1_SPACE_USED |
+					FATTR4_WORD1_TIME_METADATA |
+					FATTR4_WORD1_TIME_MODIFY))
+			goto out_bad_bitmap;
+	}
+	READ_BUF(4);
+	READ32(attrlen);
+	READ_BUF(attrlen);
+	if (attrlen < 16) {
+		printk(KERN_NOTICE "decode_post_write_getattr: server returned bad attribute length %u\n",
+				(unsigned int)attrlen);
+		return -EIO;
+	}
+	READ64(fattr->change_attr);
+	READ64(fattr->size);
+	if (bmval1 & FATTR4_WORD1_SPACE_USED)
+		READ64(fattr->du.nfs3.used);
+	if (bmval1 & FATTR4_WORD1_TIME_METADATA)
+		READTIME(fattr->ctime);
+	if (bmval1 & FATTR4_WORD1_TIME_MODIFY)
+		READTIME(fattr->mtime);
+	fattr->bitmap[0] = bmval0;
+	fattr->bitmap[1] = bmval1;
+	return 0;
+out_bad_bitmap:
+	printk(KERN_NOTICE "decode_post_write_getattr: server returned bad attribute bitmap 0x%x/0x%x\n",
+			(unsigned int)bmval0, (unsigned int)bmval1);
+	return -EIO;
+}
+
+
+static int
 decode_getfh(struct xdr_stream *xdr, struct nfs4_getfh *getfh)
 {
 	struct nfs_fh *fh = getfh->gf_fhandle;
@@ -1883,6 +2098,9 @@
 	if (status)
 		goto out;
 	status = decode_read(&xdr, rqstp, res);
+	if (status)
+		goto out;
+	status = decode_read_getattr(&xdr, res->fattr);
 	if (!status)
 		status = -nfs_stat_to_errno(hdr.status);
 out:
@@ -1906,7 +2124,13 @@
 	status = decode_putfh(&xdr);
 	if (status)
 		goto out;
+	status = decode_pre_write_getattr(&xdr, res->fattr);
+	if (status)
+		goto out;
 	status = decode_write(&xdr, res);
+	if (status)
+		goto out;
+	status = decode_post_write_getattr(&xdr, res->fattr);
 	if (!status)
 		status = -nfs_stat_to_errno(hdr.status);
 	if (!status)
@@ -1932,7 +2156,13 @@
 	status = decode_putfh(&xdr);
 	if (status)
 		goto out;
+	status = decode_pre_write_getattr(&xdr, res->fattr);
+	if (status)
+		goto out;
 	status = decode_commit(&xdr, res);
+	if (status)
+		goto out;
+	status = decode_post_write_getattr(&xdr, res->fattr);
 	if (!status)
 		status = -nfs_stat_to_errno(hdr.status);
 out:
diff -u --recursive --new-file linux-2.5.52-02-nfsv4_write/fs/nfs/proc.c linux-2.5.52-03-nfsv4_attr/fs/nfs/proc.c
--- linux-2.5.52-02-nfsv4_write/fs/nfs/proc.c	2002-12-17 15:27:47.000000000 +0100
+++ linux-2.5.52-03-nfsv4_attr/fs/nfs/proc.c	2002-12-17 15:28:07.000000000 +0100
@@ -48,6 +48,18 @@
 
 extern struct rpc_procinfo nfs_procedures[];
 
+static void
+nfs_write_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
+{
+	if (!(fattr->valid & NFS_ATTR_WCC)) {
+		fattr->pre_size  = NFS_CACHE_ISIZE(inode);
+		fattr->pre_mtime = NFS_CACHE_MTIME(inode);
+		fattr->pre_ctime = NFS_CACHE_CTIME(inode);
+		fattr->valid |= NFS_ATTR_WCC;
+	}
+	nfs_refresh_inode(inode, fattr);
+}
+
 /*
  * Bare-bones access to getattr: this is for nfs_read_super.
  */
@@ -166,6 +178,8 @@
 	fattr->valid = 0;
 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
 
+	if (status >= 0)
+		nfs_refresh_inode(inode, fattr);
 	dprintk("NFS reply read: %d\n", status);
 	*eofp = res.eof;
 	return status;
@@ -205,6 +219,9 @@
 		flags |= NFS_RPC_SWAPFLAGS;
 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
 
+	if (status >= 0)
+		nfs_write_refresh_inode(inode, fattr);
+
 	dprintk("NFS reply write: %d\n", status);
 	verf->committed = NFS_FILE_SYNC;      /* NFSv2 always syncs data */
 	return status < 0? status : count;
@@ -521,6 +538,16 @@
 extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
 
 static void
+nfs_read_done(struct rpc_task *task)
+{
+	struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
+
+	if (task->tk_status >= 0)
+		nfs_refresh_inode(data->inode, data->res.fattr);
+	nfs_readpage_result(task);
+}
+
+static void
 nfs_proc_read_setup(struct nfs_read_data *data, unsigned int count)
 {
 	struct rpc_task		*task = &data->task;
@@ -548,7 +575,7 @@
 	flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs_readpage_result, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), nfs_read_done, flags);
 	task->tk_calldata = data;
 	/* Release requests */
 	task->tk_release = nfs_readdata_release;
@@ -557,6 +584,16 @@
 }
 
 static void
+nfs_write_done(struct rpc_task *task)
+{
+	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+
+	if (task->tk_status >= 0)
+		nfs_write_refresh_inode(data->inode, data->res.fattr);
+	nfs_writeback_done(task);
+}
+
+static void
 nfs_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
 {
 	struct rpc_task		*task = &data->task;
@@ -587,7 +624,7 @@
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs_writeback_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), nfs_write_done, flags);
 	task->tk_calldata = data;
 	/* Release requests */
 	task->tk_release = nfs_writedata_release;
diff -u --recursive --new-file linux-2.5.52-02-nfsv4_write/fs/nfs/read.c linux-2.5.52-03-nfsv4_attr/fs/nfs/read.c
--- linux-2.5.52-02-nfsv4_write/fs/nfs/read.c	2002-12-17 15:27:29.000000000 +0100
+++ linux-2.5.52-03-nfsv4_attr/fs/nfs/read.c	2002-12-17 15:28:07.000000000 +0100
@@ -100,7 +100,6 @@
 		lock_kernel();
 		result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags,
 						offset, rsize, page, &eof);
-		nfs_refresh_inode(inode, &fattr);
 		unlock_kernel();
 
 		/*
@@ -258,14 +257,12 @@
 nfs_readpage_result(struct rpc_task *task)
 {
 	struct nfs_read_data	*data = (struct nfs_read_data *) task->tk_calldata;
-	struct inode		*inode = data->inode;
 	struct nfs_fattr	*fattr = &data->fattr;
 	unsigned int count = data->res.count;
 
 	dprintk("NFS: %4d nfs_readpage_result, (status %d)\n",
 		task->tk_pid, task->tk_status);
 
-	nfs_refresh_inode(inode, fattr);
 	while (!list_empty(&data->pages)) {
 		struct nfs_page *req = nfs_list_entry(data->pages.next);
 		struct page *page = req->wb_page;
diff -u --recursive --new-file linux-2.5.52-02-nfsv4_write/fs/nfs/write.c linux-2.5.52-03-nfsv4_attr/fs/nfs/write.c
--- linux-2.5.52-02-nfsv4_write/fs/nfs/write.c	2002-12-17 15:27:47.000000000 +0100
+++ linux-2.5.52-03-nfsv4_attr/fs/nfs/write.c	2002-12-17 15:28:07.000000000 +0100
@@ -125,23 +125,6 @@
 }
 
 /*
- * This function will be used to simulate weak cache consistency
- * under NFSv2 when the NFSv3 attribute patch is included.
- * For the moment, we just call nfs_refresh_inode().
- */
-static __inline__ int
-nfs_write_attributes(struct inode *inode, struct nfs_fattr *fattr)
-{
-	if ((fattr->valid & NFS_ATTR_FATTR) && !(fattr->valid & NFS_ATTR_WCC)) {
-		fattr->pre_size  = NFS_CACHE_ISIZE(inode);
-		fattr->pre_mtime = NFS_CACHE_MTIME(inode);
-		fattr->pre_ctime = NFS_CACHE_CTIME(inode);
-		fattr->valid |= NFS_ATTR_WCC;
-	}
-	return nfs_refresh_inode(inode, fattr);
-}
-
-/*
  * Write a page synchronously.
  * Offset is the data offset within the page.
  */
@@ -178,7 +161,6 @@
 
 		result = NFS_PROTO(inode)->write(inode, cred, &fattr, flags,
 						 offset, wsize, page, &verf);
-		nfs_write_attributes(inode, &fattr);
 
 		if (result < 0) {
 			/* Must mark the page invalid after I/O error */
@@ -893,7 +875,6 @@
 	 *	  writebacks since the page->count is kept > 1 for as long
 	 *	  as the page has a write request pending.
 	 */
-	nfs_write_attributes(inode, &data->fattr);
 	while (!list_empty(&data->pages)) {
 		req = nfs_list_entry(data->pages.next);
 		nfs_list_remove_request(req);
@@ -1018,12 +999,10 @@
 {
 	struct nfs_write_data	*data = (struct nfs_write_data *)task->tk_calldata;
 	struct nfs_page		*req;
-	struct inode		*inode = data->inode;
 
         dprintk("NFS: %4d nfs_commit_done (status %d)\n",
                                 task->tk_pid, task->tk_status);
 
-	nfs_write_attributes(inode, &data->fattr);
 	while (!list_empty(&data->pages)) {
 		req = nfs_list_entry(data->pages.next);
 		nfs_list_remove_request(req);
diff -u --recursive --new-file linux-2.5.52-02-nfsv4_write/include/linux/nfs_xdr.h linux-2.5.52-03-nfsv4_attr/include/linux/nfs_xdr.h
--- linux-2.5.52-02-nfsv4_write/include/linux/nfs_xdr.h	2002-12-17 15:27:47.000000000 +0100
+++ linux-2.5.52-03-nfsv4_attr/include/linux/nfs_xdr.h	2002-12-17 15:28:07.000000000 +0100
@@ -35,8 +35,11 @@
 	struct timespec		atime;
 	struct timespec		mtime;
 	struct timespec		ctime;
+#ifdef CONFIG_NFS_V4
+	__u32			bitmap[2];	/* NFSv4 returned attribute bitmap */
 	__u64			change_attr;	/* NFSv4 change attribute */
 	__u64			pre_change_attr;/* pre-op NFSv4 change attribute */
+#endif
 	unsigned long		timestamp;
 };
 


-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* Re: Intel P6 vs P7 system call performance
From: Linus Torvalds @ 2002-12-17 18:24 UTC (permalink / raw)
  To: Ulrich Drepper, Matti Aarnio
  Cc: Hugh Dickins, Dave Jones, Ingo Molnar, linux-kernel, hpa
In-Reply-To: <Pine.LNX.4.44.0212170948380.2702-100000@home.transmeta.com>



On Tue, 17 Dec 2002, Linus Torvalds wrote:
>
> Uli, how about I just add one ne warchitecture-specific ELF AT flag, which
> is the "base of sysinfo page". Right now that page is all zeroes except
> for the system call trampoline at the beginning, but we might want to add
> other system information to the page in the future (it is readable, after
> all).

Here's the suggested (totally untested as of yet) patch:

 - it moves the system call page to 0xffffe000 instead, leaving an
   unmapped page at the very top of the address space. So trying to
   dereference -1 will cause a SIGSEGV.

 - it adds the AT_SYSINFO elf entry on x86 that points to the system page.

Thus glibc startup should be able to just do

	ptr = default_int80_syscall;
	if (AT_SYSINFO entry found)
		ptr = value(AT_SYSINFO)

and then you can just do a

	call *ptr

to do a system call regardless of kernel version. This also allows the
kernel to later move the page around as it sees fit.

The advantage of using an AT_SYSINFO entry is that

 - no new system call needed to figure anything out
 - backwards compatibility (ie old kernels automatically detected)
 - I think glibc already parses the AT entries at startup anyway

so it _looks_ like a perfect way to do this.

		Linus

----
===== arch/i386/kernel/entry.S 1.42 vs edited =====
--- 1.42/arch/i386/kernel/entry.S	Mon Dec 16 21:39:04 2002
+++ edited/arch/i386/kernel/entry.S	Tue Dec 17 10:13:16 2002
@@ -232,7 +232,7 @@
 #endif

 /* Points to after the "sysenter" instruction in the vsyscall page */
-#define SYSENTER_RETURN 0xfffff007
+#define SYSENTER_RETURN 0xffffe007

 	# sysenter call handler stub
 	ALIGN
===== include/asm-i386/elf.h 1.3 vs edited =====
--- 1.3/include/asm-i386/elf.h	Thu Oct 17 00:48:55 2002
+++ edited/include/asm-i386/elf.h	Tue Dec 17 10:12:58 2002
@@ -100,6 +100,12 @@

 #define ELF_PLATFORM  (system_utsname.machine)

+/*
+ * Architecture-neutral AT_ values in 0-17, leave some room
+ * for more of them, start the x86-specific ones at 32.
+ */
+#define AT_SYSINFO	32
+
 #ifdef __KERNEL__
 #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)

@@ -115,6 +121,11 @@
 extern void dump_smp_unlazy_fpu(void);
 #define ELF_CORE_SYNC dump_smp_unlazy_fpu
 #endif
+
+#define ARCH_DLINFO					\
+do {							\
+		NEW_AUX_ENT(AT_SYSINFO, 0xffffe000);	\
+} while (0)

 #endif

===== include/asm-i386/fixmap.h 1.9 vs edited =====
--- 1.9/include/asm-i386/fixmap.h	Mon Dec 16 21:39:04 2002
+++ edited/include/asm-i386/fixmap.h	Tue Dec 17 10:11:31 2002
@@ -42,8 +42,8 @@
  * task switches.
  */
 enum fixed_addresses {
-	FIX_VSYSCALL,
 	FIX_HOLE,
+	FIX_VSYSCALL,
 #ifdef CONFIG_X86_LOCAL_APIC
 	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
 #endif


^ permalink raw reply

* [PATCH] Clean up NFSv4 WRITE xdr path
From: Trond Myklebust @ 2002-12-17 18:15 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: NFS maillist


The following patch creates a clean XDR path for the NFSv4 write requests
instead of routing through encode_compound()/decode_compound().

Cheers,
  Trond

diff -u --recursive --new-file linux-2.5.52-01-nfsv4_read/fs/nfs/nfs3proc.c linux-2.5.52-02-nfsv4_write/fs/nfs/nfs3proc.c
--- linux-2.5.52-01-nfsv4_read/fs/nfs/nfs3proc.c	2002-12-17 15:27:29.000000000 +0100
+++ linux-2.5.52-02-nfsv4_write/fs/nfs/nfs3proc.c	2002-12-17 15:27:47.000000000 +0100
@@ -730,12 +730,9 @@
 static void
 nfs3_write_done(struct rpc_task *task)
 {
-	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
-
 	if (nfs3_async_handle_jukebox(task))
 		return;
-	nfs_writeback_done(task, data->u.v3.args.stable,
-			   data->u.v3.args.count, data->u.v3.res.count);
+	nfs_writeback_done(task);
 }
 
 static void
@@ -748,8 +745,8 @@
 	int			flags;
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_WRITE],
-		.rpc_argp	= &data->u.v3.args,
-		.rpc_resp	= &data->u.v3.res,
+		.rpc_argp	= &data->args,
+		.rpc_resp	= &data->res,
 		.rpc_cred	= data->cred,
 	};
 
@@ -762,15 +759,15 @@
 		stable = NFS_UNSTABLE;
 	
 	req = nfs_list_entry(data->pages.next);
-	data->u.v3.args.fh     = NFS_FH(inode);
-	data->u.v3.args.offset = req_offset(req) + req->wb_offset;
-	data->u.v3.args.pgbase = req->wb_offset;
-	data->u.v3.args.count  = count;
-	data->u.v3.args.stable = stable;
-	data->u.v3.args.pages  = data->pagevec;
-	data->u.v3.res.fattr   = &data->fattr;
-	data->u.v3.res.count   = count;
-	data->u.v3.res.verf    = &data->verf;
+	data->args.fh     = NFS_FH(inode);
+	data->args.offset = req_offset(req) + req->wb_offset;
+	data->args.pgbase = req->wb_offset;
+	data->args.count  = count;
+	data->args.stable = stable;
+	data->args.pages  = data->pagevec;
+	data->res.fattr   = &data->fattr;
+	data->res.count   = count;
+	data->res.verf    = &data->verf;
 
 	/* Set the initial flags for the task.  */
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
@@ -800,17 +797,17 @@
 	int			flags;
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_COMMIT],
-		.rpc_argp	= &data->u.v3.args,
-		.rpc_resp	= &data->u.v3.res,
+		.rpc_argp	= &data->args,
+		.rpc_resp	= &data->res,
 		.rpc_cred	= data->cred,
 	};
 
-	data->u.v3.args.fh     = NFS_FH(data->inode);
-	data->u.v3.args.offset = start;
-	data->u.v3.args.count  = len;
-	data->u.v3.res.count   = len;
-	data->u.v3.res.fattr   = &data->fattr;
-	data->u.v3.res.verf    = &data->verf;
+	data->args.fh     = NFS_FH(data->inode);
+	data->args.offset = start;
+	data->args.count  = len;
+	data->res.count   = len;
+	data->res.fattr   = &data->fattr;
+	data->res.verf    = &data->verf;
 	
 	/* Set the initial flags for the task.  */
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
diff -u --recursive --new-file linux-2.5.52-01-nfsv4_read/fs/nfs/nfs4proc.c linux-2.5.52-02-nfsv4_write/fs/nfs/nfs4proc.c
--- linux-2.5.52-01-nfsv4_read/fs/nfs/nfs4proc.c	2002-12-17 15:27:29.000000000 +0100
+++ linux-2.5.52-02-nfsv4_write/fs/nfs/nfs4proc.c	2002-12-17 15:27:47.000000000 +0100
@@ -94,19 +94,6 @@
 }
 
 static void
-nfs4_setup_commit(struct nfs4_compound *cp, u64 start, u32 len, struct nfs_writeverf *verf)
-{
-	struct nfs4_commit *commit = GET_OP(cp, commit);
-
-	commit->co_start = start;
-	commit->co_len = len;
-	commit->co_verifier = verf;
-
-	OPNUM(cp) = OP_COMMIT;
-	cp->req_nops++;
-}
-
-static void
 nfs4_setup_create_dir(struct nfs4_compound *cp, struct qstr *name,
 		      struct iattr *sattr, struct nfs4_change_info *info)
 {
@@ -577,26 +564,6 @@
 }
 
 static void
-nfs4_setup_write(struct nfs4_compound *cp, u64 offset, u32 length, int stable,
-		 struct page **pages, unsigned int pgbase, u32 *bytes_written,
-		 struct nfs_writeverf *verf)
-{
-	struct nfs4_write *write = GET_OP(cp, write);
-
-	write->wr_offset = offset;
-	write->wr_stable_how = stable;
-	write->wr_len = length;
-	write->wr_bytes_written = bytes_written;
-	write->wr_verf = verf;
-
-	write->wr_pages = pages;
-	write->wr_pgbase = pgbase;
-
-	OPNUM(cp) = OP_WRITE;
-	cp->req_nops++;
-}
-
-static void
 renew_lease(struct nfs_server *server, unsigned long timestamp)
 {
 	spin_lock(&renew_lock);
@@ -1026,23 +993,32 @@
 		unsigned int base, unsigned int count,
 		struct page *page, struct nfs_writeverf *verf)
 {
-	u64			offset = page_offset(page) + base;
-	struct nfs4_compound	compound;
-	struct nfs4_op		ops[2];
-	u32			bytes_written;
-	int			stable = (flags & NFS_RW_SYNC) ? NFS_FILE_SYNC : NFS_UNSTABLE;
+	struct nfs_server *server = NFS_SERVER(inode);
+	uint64_t offset = page_offset(page) + base;
+	struct nfs_writeargs arg = {
+		.fh		= NFS_FH(inode),
+		.offset		= offset,
+		.count		= count,
+		.stable		= (flags & NFS_RW_SYNC) ? NFS_FILE_SYNC : NFS_UNSTABLE,
+		.pgbase		= base,
+		.pages		= &page,
+	};
+	struct nfs_writeres res = {
+		.fattr		= fattr,
+		.count		= count,
+		.verf		= verf,
+	};
+	struct rpc_message msg = {
+		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_WRITE],
+		.rpc_argp	= &arg,
+		.rpc_resp	= &res,
+		.rpc_cred	= cred,
+	};
 	int			rpcflags = (flags & NFS_RW_SWAP) ? NFS_RPC_SWAPFLAGS : 0;
-	int			status;
 
+	dprintk("NFS call  write %d @ %Ld\n", count, (long long)offset);
 	fattr->valid = 0;
-	nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "write [sync]");
-	nfs4_setup_putfh(&compound, NFS_FH(inode));
-	nfs4_setup_write(&compound, offset, count, stable, &page, base, &bytes_written, verf);
-	status = nfs4_call_compound(&compound, cred, rpcflags);
-	
-	if (status >= 0)
-		status = bytes_written;
-	return status;
+	return rpc_call_sync(server->client, &msg, rpcflags);
 }
 
 static int
@@ -1410,20 +1386,20 @@
 {
 	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
 	
-	process_lease(&data->u.v4.compound);
-	nfs_writeback_done(task, data->u.v4.arg_stable,
-			   data->u.v4.arg_count, data->u.v4.res_count);
+	if (task->tk_status > 0)
+		renew_lease(NFS_SERVER(data->inode), data->timestamp);
+	/* Call back common NFS writeback processing */
+	nfs_writeback_done(task);
 }
 
 static void
 nfs4_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
 {
 	struct rpc_task	*task = &data->task;
-	struct nfs4_compound *cp = &data->u.v4.compound;
 	struct rpc_message msg = {
-		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMPOUND],
-		.rpc_argp = cp,
-		.rpc_resp = cp,
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE],
+		.rpc_argp = &data->args,
+		.rpc_resp = &data->res,
 		.rpc_cred = data->cred,
 	};
 	struct inode *inode = data->inode;
@@ -1439,11 +1415,16 @@
 	} else
 		stable = NFS_UNSTABLE;
 
-	nfs4_setup_compound(cp, data->u.v4.ops, NFS_SERVER(inode), "write [async]");
-	nfs4_setup_putfh(cp, NFS_FH(inode));
-	nfs4_setup_write(cp, req_offset(req) + req->wb_offset,
-			 count, stable, data->pagevec, req->wb_offset,
-			 &data->u.v4.res_count, &data->verf);
+	data->args.fh     = NFS_FH(inode);
+	data->args.offset = req_offset(req) + req->wb_offset;
+	data->args.pgbase = req->wb_offset;
+	data->args.count  = count;
+	data->args.stable = stable;
+	data->args.pages  = data->pagevec;
+	data->res.fattr   = &data->fattr;
+	data->res.count   = count;
+	data->res.verf    = &data->verf;
+	data->timestamp   = jiffies;
 
 	/* Set the initial flags for the task.  */
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
@@ -1458,37 +1439,30 @@
 }
 
 static void
-nfs4_commit_done(struct rpc_task *task)
-{
-	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
-	
-	process_lease(&data->u.v4.compound);
-	nfs_commit_done(task);
-}
-
-static void
 nfs4_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how)
 {
 	struct rpc_task	*task = &data->task;
-	struct nfs4_compound *cp = &data->u.v4.compound;
 	struct rpc_message msg = {
-		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMPOUND],
-		.rpc_argp = cp,
-		.rpc_resp = cp,
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
+		.rpc_argp = &data->args,
+		.rpc_resp = &data->res,
 		.rpc_cred = data->cred,
 	};	
 	struct inode *inode = data->inode;
 	int flags;
 	
-	nfs4_setup_compound(cp, data->u.v4.ops, NFS_SERVER(inode), "commit [async]");
-	nfs4_setup_putfh(cp, NFS_FH(inode));
-	nfs4_setup_commit(cp, start, len, &data->verf);
+	data->args.fh     = NFS_FH(data->inode);
+	data->args.offset = start;
+	data->args.count  = len;
+	data->res.count   = len;
+	data->res.fattr   = &data->fattr;
+	data->res.verf    = &data->verf;
 	
 	/* Set the initial flags for the task.  */
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs4_commit_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), nfs_commit_done, flags);
 	task->tk_calldata = data;
 	/* Release requests */
 	task->tk_release = nfs_commit_release;
diff -u --recursive --new-file linux-2.5.52-01-nfsv4_read/fs/nfs/nfs4xdr.c linux-2.5.52-02-nfsv4_write/fs/nfs/nfs4xdr.c
--- linux-2.5.52-01-nfsv4_read/fs/nfs/nfs4xdr.c	2002-12-17 15:27:29.000000000 +0100
+++ linux-2.5.52-02-nfsv4_write/fs/nfs/nfs4xdr.c	2002-12-17 15:27:47.000000000 +0100
@@ -87,6 +87,19 @@
 #define NFS4_dec_read_sz	compound_decode_hdr_maxsz + \
 				decode_putfh_maxsz + \
 				op_decode_hdr_maxsz + 2
+#define NFS4_enc_write_sz	compound_encode_hdr_maxsz + \
+				encode_putfh_maxsz + \
+				op_encode_hdr_maxsz + 8
+#define NFS4_dec_write_sz	compound_decode_hdr_maxsz + \
+				decode_putfh_maxsz + \
+				op_decode_hdr_maxsz + 4
+#define NFS4_enc_commit_sz	compound_encode_hdr_maxsz + \
+				encode_putfh_maxsz + \
+				op_encode_hdr_maxsz + 3
+#define NFS4_dec_commit_sz	compound_decode_hdr_maxsz + \
+				decode_putfh_maxsz + \
+				op_decode_hdr_maxsz + 2
+
 
 static struct {
 	unsigned int	mode;
@@ -332,14 +345,14 @@
 }
 
 static int
-encode_commit(struct xdr_stream *xdr, struct nfs4_commit *commit)
+encode_commit(struct xdr_stream *xdr, struct nfs_writeargs *args)
 {
 	uint32_t *p;
         
         RESERVE_SPACE(16);
         WRITE32(OP_COMMIT);
-        WRITE64(commit->co_start);
-        WRITE32(commit->co_len);
+        WRITE64(args->offset);
+        WRITE32(args->count);
 
         return 0;
 }
@@ -705,9 +718,8 @@
 }
 
 static int
-encode_write(struct xdr_stream *xdr, struct nfs4_write *write, struct rpc_rqst *req)
+encode_write(struct xdr_stream *xdr, struct nfs_writeargs *args)
 {
-	struct xdr_buf *sndbuf = &req->rq_snd_buf;
 	uint32_t *p;
 
 	RESERVE_SPACE(36);
@@ -716,11 +728,11 @@
 	WRITE32(0xffffffff);
 	WRITE32(0xffffffff);
 	WRITE32(0xffffffff);
-	WRITE64(write->wr_offset);
-	WRITE32(write->wr_stable_how);
-	WRITE32(write->wr_len);
+	WRITE64(args->offset);
+	WRITE32(args->stable);
+	WRITE32(args->count);
 
-	xdr_encode_pages(sndbuf, write->wr_pages, write->wr_pgbase, write->wr_len);
+	xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
 
 	return 0;
 }
@@ -746,9 +758,6 @@
 		case OP_CLOSE:
 			status = encode_close(xdr, &cp->ops[i].u.close);
 			break;
-		case OP_COMMIT:
-			status = encode_commit(xdr, &cp->ops[i].u.commit);
-			break;
 		case OP_CREATE:
 			status = encode_create(xdr, &cp->ops[i].u.create);
 			break;
@@ -806,9 +815,6 @@
 		case OP_SETCLIENTID_CONFIRM:
 			status = encode_setclientid_confirm(xdr, cp->ops[i].u.setclientid_confirm);
 			break;
-		case OP_WRITE:
-			status = encode_write(xdr, &cp->ops[i].u.write, req);
-			break;
 		default:
 			BUG();
 		}
@@ -869,6 +875,49 @@
 	return status;
 }
 
+/*
+ * Encode a WRITE request
+ */
+static int
+nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr = {
+		.nops   = 2,
+	};
+	int status;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_compound_hdr(&xdr, &hdr);
+	status = encode_putfh(&xdr, args->fh);
+	if (status)
+		goto out;
+	status = encode_write(&xdr, args);
+out:
+	return status;
+}
+
+/*
+ * Encode a COMMIT request
+ */
+static int
+nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr = {
+		.nops   = 2,
+	};
+	int status;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_compound_hdr(&xdr, &hdr);
+	status = encode_putfh(&xdr, args->fh);
+	if (status)
+		goto out;
+	status = encode_commit(&xdr, args);
+out:
+	return status;
+}
 
 /*
  * START OF "GENERIC" DECODE ROUTINES.
@@ -1022,7 +1071,7 @@
 }
 
 static int
-decode_commit(struct xdr_stream *xdr, struct nfs4_commit *commit)
+decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res)
 {
 	uint32_t *p;
 	int status;
@@ -1031,7 +1080,7 @@
 	if (status)
 		return status;
 	READ_BUF(8);
-	COPYMEM(commit->co_verifier->verifier, 8);
+	COPYMEM(res->verf->verifier, 8);
 	return 0;
 }
 
@@ -1672,7 +1721,7 @@
 }
 
 static int
-decode_write(struct xdr_stream *xdr, struct nfs4_write *write)
+decode_write(struct xdr_stream *xdr, struct nfs_writeres *res)
 {
 	uint32_t *p;
 	int status;
@@ -1682,11 +1731,9 @@
 		return status;
 
 	READ_BUF(16);
-	READ32(*write->wr_bytes_written);
-	if (*write->wr_bytes_written > write->wr_len)
-		return -EIO;
-	READ32(write->wr_verf->committed);
-	COPYMEM(write->wr_verf->verifier, 8);
+	READ32(res->count);
+	READ32(res->verf->committed);
+	COPYMEM(res->verf->verifier, 8);
 	return 0;
 }
 
@@ -1726,9 +1773,6 @@
 		case OP_CLOSE:
 			status = decode_close(xdr, &op->u.close);
 			break;
-		case OP_COMMIT:
-			status = decode_commit(xdr, &op->u.commit);
-			break;
 		case OP_CREATE:
 			status = decode_create(xdr, &op->u.create);
 			break;
@@ -1786,9 +1830,6 @@
 		case OP_SETCLIENTID_CONFIRM:
 			status = decode_setclientid_confirm(xdr);
 			break;
-		case OP_WRITE:
-			status = decode_write(xdr, &op->u.write);
-			break;
 		default:
 			BUG();
 			return -EIO;
@@ -1848,6 +1889,56 @@
 	return status;
 }
 
+/*
+ * Decode WRITE response
+ */
+static int
+nfs4_xdr_dec_write(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_writeres *res)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr;
+	int status;
+
+	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+	status = decode_compound_hdr(&xdr, &hdr);
+	if (status)
+		goto out;
+	status = decode_putfh(&xdr);
+	if (status)
+		goto out;
+	status = decode_write(&xdr, res);
+	if (!status)
+		status = -nfs_stat_to_errno(hdr.status);
+	if (!status)
+		status = res->count;
+out:
+	return status;
+}
+
+/*
+ * Decode COMMIT response
+ */
+static int
+nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_writeres *res)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr;
+	int status;
+
+	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+	status = decode_compound_hdr(&xdr, &hdr);
+	if (status)
+		goto out;
+	status = decode_putfh(&xdr);
+	if (status)
+		goto out;
+	status = decode_commit(&xdr, res);
+	if (!status)
+		status = -nfs_stat_to_errno(hdr.status);
+out:
+	return status;
+}
+
 uint32_t *
 nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
 {
@@ -1901,6 +1992,8 @@
 struct rpc_procinfo	nfs4_procedures[] = {
   PROC(COMPOUND,	enc_compound,	dec_compound),
   PROC(READ,		enc_read,	dec_read),
+  PROC(WRITE,		enc_write,	dec_write),
+  PROC(COMMIT,		enc_commit,	dec_commit),
 };
 
 struct rpc_version		nfs_version4 = {
diff -u --recursive --new-file linux-2.5.52-01-nfsv4_read/fs/nfs/proc.c linux-2.5.52-02-nfsv4_write/fs/nfs/proc.c
--- linux-2.5.52-01-nfsv4_read/fs/nfs/proc.c	2002-12-17 15:27:29.000000000 +0100
+++ linux-2.5.52-02-nfsv4_write/fs/nfs/proc.c	2002-12-17 15:27:47.000000000 +0100
@@ -557,14 +557,6 @@
 }
 
 static void
-nfs_write_done(struct rpc_task *task)
-{
-	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
-	nfs_writeback_done(task, data->u.v3.args.stable,
-			   data->u.v3.args.count, data->u.v3.res.count);
-}
-
-static void
 nfs_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
 {
 	struct rpc_task		*task = &data->task;
@@ -573,29 +565,29 @@
 	int			flags;
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs_procedures[NFSPROC_WRITE],
-		.rpc_argp	= &data->u.v3.args,
-		.rpc_resp	= &data->u.v3.res,
+		.rpc_argp	= &data->args,
+		.rpc_resp	= &data->res,
 		.rpc_cred	= data->cred,
 	};
 
 	/* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */
 	
 	req = nfs_list_entry(data->pages.next);
-	data->u.v3.args.fh     = NFS_FH(inode);
-	data->u.v3.args.offset = req_offset(req) + req->wb_offset;
-	data->u.v3.args.pgbase = req->wb_offset;
-	data->u.v3.args.count  = count;
-	data->u.v3.args.stable = NFS_FILE_SYNC;
-	data->u.v3.args.pages  = data->pagevec;
-	data->u.v3.res.fattr   = &data->fattr;
-	data->u.v3.res.count   = count;
-	data->u.v3.res.verf    = &data->verf;
+	data->args.fh     = NFS_FH(inode);
+	data->args.offset = req_offset(req) + req->wb_offset;
+	data->args.pgbase = req->wb_offset;
+	data->args.count  = count;
+	data->args.stable = NFS_FILE_SYNC;
+	data->args.pages  = data->pagevec;
+	data->res.fattr   = &data->fattr;
+	data->res.count   = count;
+	data->res.verf    = &data->verf;
 
 	/* Set the initial flags for the task.  */
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs_write_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), nfs_writeback_done, flags);
 	task->tk_calldata = data;
 	/* Release requests */
 	task->tk_release = nfs_writedata_release;
diff -u --recursive --new-file linux-2.5.52-01-nfsv4_read/fs/nfs/write.c linux-2.5.52-02-nfsv4_write/fs/nfs/write.c
--- linux-2.5.52-01-nfsv4_read/fs/nfs/write.c	2002-12-14 18:42:09.000000000 +0100
+++ linux-2.5.52-02-nfsv4_write/fs/nfs/write.c	2002-12-17 15:27:47.000000000 +0100
@@ -841,10 +841,11 @@
  * This function is called when the WRITE call is complete.
  */
 void
-nfs_writeback_done(struct rpc_task *task, int stable,
-		   unsigned int arg_count, unsigned int res_count)
+nfs_writeback_done(struct rpc_task *task)
 {
 	struct nfs_write_data	*data = (struct nfs_write_data *) task->tk_calldata;
+	struct nfs_writeargs	*argp = &data->args;
+	struct nfs_writeres	*resp = &data->res;
 	struct inode		*inode = data->inode;
 	struct nfs_page		*req;
 	struct page		*page;
@@ -853,7 +854,7 @@
 		task->tk_pid, task->tk_status);
 
 	/* We can't handle that yet but we check for it nevertheless */
-	if (res_count < arg_count && task->tk_status >= 0) {
+	if (resp->count < argp->count && task->tk_status >= 0) {
 		static unsigned long    complain;
 		if (time_before(complain, jiffies)) {
 			printk(KERN_WARNING
@@ -865,7 +866,7 @@
 		task->tk_status = -EIO;
 	}
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-	if (data->verf.committed < stable && task->tk_status >= 0) {
+	if (data->verf.committed < argp->stable && task->tk_status >= 0) {
 		/* We tried a write call, but the server did not
 		 * commit data to stable storage even though we
 		 * requested it.
@@ -880,7 +881,7 @@
 			dprintk("NFS: faulty NFS server %s:"
 				" (committed = %d) != (stable = %d)\n",
 				NFS_SERVER(inode)->hostname,
-				data->verf.committed, stable);
+				data->verf.committed, argp->stable);
 			complain = jiffies + 300 * HZ;
 		}
 	}
@@ -917,7 +918,7 @@
 		end_page_writeback(page);
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-		if (stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) {
+		if (argp->stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) {
 			nfs_inode_remove_request(req);
 			dprintk(" OK\n");
 			goto next;
diff -u --recursive --new-file linux-2.5.52-01-nfsv4_read/include/linux/nfs4.h linux-2.5.52-02-nfsv4_write/include/linux/nfs4.h
--- linux-2.5.52-01-nfsv4_read/include/linux/nfs4.h	2002-12-17 15:27:29.000000000 +0100
+++ linux-2.5.52-02-nfsv4_write/include/linux/nfs4.h	2002-12-17 15:27:47.000000000 +0100
@@ -204,6 +204,8 @@
 	NFSPROC4_CLNT_NULL = 0,		/* Unused */
 	NFSPROC4_CLNT_COMPOUND,		/* Soon to be unused */
 	NFSPROC4_CLNT_READ,
+	NFSPROC4_CLNT_WRITE,
+	NFSPROC4_CLNT_COMMIT,
 };
 
 #endif
diff -u --recursive --new-file linux-2.5.52-01-nfsv4_read/include/linux/nfs_fs.h linux-2.5.52-02-nfsv4_write/include/linux/nfs_fs.h
--- linux-2.5.52-01-nfsv4_read/include/linux/nfs_fs.h	2002-12-17 15:27:29.000000000 +0100
+++ linux-2.5.52-02-nfsv4_write/include/linux/nfs_fs.h	2002-12-17 15:27:47.000000000 +0100
@@ -295,8 +295,7 @@
 extern int  nfs_writepages(struct address_space *, struct writeback_control *);
 extern int  nfs_flush_incompatible(struct file *file, struct page *page);
 extern int  nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
-extern void nfs_writeback_done(struct rpc_task *task, int stable,
-			       unsigned int arg_count, unsigned int res_count);
+extern void nfs_writeback_done(struct rpc_task *task);
 extern void nfs_writedata_release(struct rpc_task *task);
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
diff -u --recursive --new-file linux-2.5.52-01-nfsv4_read/include/linux/nfs_xdr.h linux-2.5.52-02-nfsv4_write/include/linux/nfs_xdr.h
--- linux-2.5.52-01-nfsv4_read/include/linux/nfs_xdr.h	2002-12-17 15:27:29.000000000 +0100
+++ linux-2.5.52-02-nfsv4_write/include/linux/nfs_xdr.h	2002-12-17 15:27:47.000000000 +0100
@@ -346,12 +346,6 @@
 	u32				cl_seqid;          /* request */
 };
 
-struct nfs4_commit {
-	u64				co_start;          /* request */
-	u32				co_len;            /* request */
-	struct nfs_writeverf *		co_verifier;       /* response */
-};
-
 struct nfs4_create {
 	u32				cr_ftype;          /* request */
 	union {                                            /* request */
@@ -467,22 +461,11 @@
 	struct nfs4_client *		sc_state;	  /* response */
 };
 
-struct nfs4_write {
-	u64				wr_offset;        /* request */
-	u32				wr_stable_how;    /* request */
-	u32				wr_len;           /* request */
-	u32 *				wr_bytes_written; /* response */
-	struct nfs_writeverf *		wr_verf;          /* response */
-	struct page **			wr_pages;   /* zero-copy data */
-	unsigned int			wr_pgbase;  /* zero-copy data */
-};
-
 struct nfs4_op {
 	u32				opnum;
 	union {
 		struct nfs4_access	access;
 		struct nfs4_close	close;
-		struct nfs4_commit	commit;
 		struct nfs4_create	create;
 		struct nfs4_getattr	getattr;
 		struct nfs4_getfh	getfh;
@@ -499,7 +482,6 @@
 		struct nfs4_setattr	setattr;
 		struct nfs4_setclientid	setclientid;
 		struct nfs4_client *	setclientid_confirm;
-		struct nfs4_write	write;
 	} u;
 };
 
@@ -553,21 +535,11 @@
 	struct nfs_writeverf	verf;
 	struct list_head	pages;		/* Coalesced requests we wish to flush */
 	struct page		*pagevec[NFS_WRITE_MAXIOV];
-	union {
-		struct {
-			struct nfs_writeargs	args;		/* argument struct */
-			struct nfs_writeres	res;		/* result struct */
-		} v3;
+	struct nfs_writeargs	args;		/* argument struct */
+	struct nfs_writeres	res;		/* result struct */
 #ifdef CONFIG_NFS_V4
-		struct {
-			struct nfs4_compound  compound;
-			struct nfs4_op        ops[3];
-			u32                   arg_count;
-			u32                   arg_stable;
-			u32                   res_count;
-		} v4;
+	unsigned long		timestamp;	/* For lease renewal */
 #endif
-	} u;
 };
 
 /*


-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* [PATCH] Clean up NFSv4 READ xdr path
From: Trond Myklebust @ 2002-12-17 18:14 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: NFS maillist


The following patch creates a clean XDR path for the NFSv4 read requests
instead of routing through encode_compound()/decode_compound().
This eliminates the intermediate step of setting up a struct nfs4_compound
before proceeding to XDR encoding, and removes the large 'switch()'
statements from the codepath altogether.

Cheers,
  Trond


diff -u --recursive --new-file linux-2.5.52/fs/nfs/nfs3proc.c linux-2.5.52-01-nfsv4_read/fs/nfs/nfs3proc.c
--- linux-2.5.52/fs/nfs/nfs3proc.c	2002-11-13 15:59:23.000000000 +0100
+++ linux-2.5.52-01-nfsv4_read/fs/nfs/nfs3proc.c	2002-12-17 15:27:29.000000000 +0100
@@ -685,11 +685,10 @@
 static void
 nfs3_read_done(struct rpc_task *task)
 {
-	struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
-
 	if (nfs3_async_handle_jukebox(task))
 		return;
-	nfs_readpage_result(task, data->u.v3.res.count, data->u.v3.res.eof);
+	/* Call back common NFS readpage processing */
+	nfs_readpage_result(task);
 }
 
 static void
@@ -701,20 +700,20 @@
 	int			flags;
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_READ],
-		.rpc_argp	= &data->u.v3.args,
-		.rpc_resp	= &data->u.v3.res,
+		.rpc_argp	= &data->args,
+		.rpc_resp	= &data->res,
 		.rpc_cred	= data->cred,
 	};
 	
 	req = nfs_list_entry(data->pages.next);
-	data->u.v3.args.fh     = NFS_FH(inode);
-	data->u.v3.args.offset = req_offset(req) + req->wb_offset;
-	data->u.v3.args.pgbase = req->wb_offset;
-	data->u.v3.args.pages  = data->pagevec;
-	data->u.v3.args.count  = count;
-	data->u.v3.res.fattr   = &data->fattr;
-	data->u.v3.res.count   = count;
-	data->u.v3.res.eof     = 0;
+	data->args.fh     = NFS_FH(inode);
+	data->args.offset = req_offset(req) + req->wb_offset;
+	data->args.pgbase = req->wb_offset;
+	data->args.pages  = data->pagevec;
+	data->args.count  = count;
+	data->res.fattr   = &data->fattr;
+	data->res.count   = count;
+	data->res.eof     = 0;
 	
 	/* N.B. Do we need to test? Never called for swapfile inode */
 	flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
diff -u --recursive --new-file linux-2.5.52/fs/nfs/nfs4proc.c linux-2.5.52-01-nfsv4_read/fs/nfs/nfs4proc.c
--- linux-2.5.52/fs/nfs/nfs4proc.c	2002-11-23 04:16:55.000000000 +0100
+++ linux-2.5.52-01-nfsv4_read/fs/nfs/nfs4proc.c	2002-12-17 15:27:29.000000000 +0100
@@ -402,23 +402,6 @@
 }
 
 static void
-nfs4_setup_read(struct nfs4_compound *cp, u64 offset, u32 length,
-		struct page **pages, unsigned int pgbase, u32 *eofp, u32 *bytes_read)
-{
-	struct nfs4_read *read = GET_OP(cp, read);
-
-	read->rd_offset = offset;
-	read->rd_length = length;
-	read->rd_pages = pages;
-	read->rd_pgbase = pgbase;
-	read->rd_eof = eofp;
-	read->rd_bytes_read = bytes_read;
-
-	OPNUM(cp) = OP_READ;
-	cp->req_nops++;
-}
-
-static void
 nfs4_setup_readdir(struct nfs4_compound *cp, u64 cookie, u32 *verifier,
 		     struct page **pages, unsigned int bufsize, struct dentry *dentry)
 {
@@ -613,11 +596,18 @@
 	cp->req_nops++;
 }
 
+static void
+renew_lease(struct nfs_server *server, unsigned long timestamp)
+{
+	spin_lock(&renew_lock);
+	if (time_before(server->last_renewal,timestamp))
+		server->last_renewal = timestamp;
+	spin_unlock(&renew_lock);
+}
+
 static inline void
 process_lease(struct nfs4_compound *cp)
 {
-	struct nfs_server *server;
-	
         /*
          * Generic lease processing: If this operation contains a
 	 * lease-renewing operation, and it succeeded, update the RENEW time
@@ -634,13 +624,8 @@
          */
 	if (!cp->renew_index)
 		return;
-	if (!cp->toplevel_status || cp->resp_nops > cp->renew_index) {
-		server = cp->server;
-		spin_lock(&renew_lock);
-		if (server->last_renewal < cp->timestamp)
-			server->last_renewal = cp->timestamp;
-		spin_unlock(&renew_lock);
-	}
+	if (!cp->toplevel_status || cp->resp_nops > cp->renew_index)
+		renew_lease(cp->server, cp->timestamp);
 }
 
 static int
@@ -1003,20 +988,35 @@
 	       unsigned int base, unsigned int count,
 	       struct page *page, int *eofp)
 {
-	u64			offset = page_offset(page) + base;
-	struct nfs4_compound	compound;
-	struct nfs4_op		ops[2];
-	u32			bytes_read;
-	int			status;
+	struct nfs_server *server = NFS_SERVER(inode);
+	uint64_t offset = page_offset(page) + base;
+	struct nfs_readargs arg = {
+		.fh		= NFS_FH(inode),
+		.offset		= offset,
+		.count		= count,
+		.pgbase		= base,
+		.pages		= &page,
+	};
+	struct nfs_readres res = {
+		.fattr		= fattr,
+		.count		= count,
+	};
+	struct rpc_message msg = {
+		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_READ],
+		.rpc_argp	= &arg,
+		.rpc_resp	= &res,
+		.rpc_cred	= cred,
+	};
+	unsigned long timestamp = jiffies;
+	int status;
 
+	dprintk("NFS call  read %d @ %Ld\n", count, (long long)offset);
 	fattr->valid = 0;
-	nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "read [sync]");
-	nfs4_setup_putfh(&compound, NFS_FH(inode));
-	nfs4_setup_read(&compound, offset, count, &page, base, eofp, &bytes_read);
-	status = nfs4_call_compound(&compound, cred, 0);
-
-	if (status >= 0)
-		status = bytes_read;
+	status = rpc_call_sync(server->client, &msg, flags);
+	if (!status)
+		renew_lease(server, timestamp);
+	dprintk("NFS reply read: %d\n", status);
+	*eofp = res.eof;
 	return status;
 }
 
@@ -1363,31 +1363,35 @@
 {
 	struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
 
-	process_lease(&data->u.v4.compound);
-	nfs_readpage_result(task, data->u.v4.res_count, data->u.v4.res_eof);
+	if (task->tk_status > 0)
+		renew_lease(NFS_SERVER(data->inode), data->timestamp);
+	/* Call back common NFS readpage processing */
+	nfs_readpage_result(task);
 }
 
 static void
 nfs4_proc_read_setup(struct nfs_read_data *data, unsigned int count)
 {
 	struct rpc_task	*task = &data->task;
-	struct nfs4_compound *cp = &data->u.v4.compound;
 	struct rpc_message msg = {
-		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMPOUND],
-		.rpc_argp = cp,
-		.rpc_resp = cp,
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ],
+		.rpc_argp = &data->args,
+		.rpc_resp = &data->res,
 		.rpc_cred = data->cred,
 	};
 	struct inode *inode = data->inode;
 	struct nfs_page *req = nfs_list_entry(data->pages.next);
 	int flags;
 
-	nfs4_setup_compound(cp, data->u.v4.ops, NFS_SERVER(inode), "read [async]");
-	nfs4_setup_putfh(cp, NFS_FH(inode));
-	nfs4_setup_read(cp, req_offset(req) + req->wb_offset,
-			count, data->pagevec, req->wb_offset,
-			&data->u.v4.res_eof,
-			&data->u.v4.res_count);
+	data->args.fh     = NFS_FH(inode);
+	data->args.offset = req_offset(req) + req->wb_offset;
+	data->args.pgbase = req->wb_offset;
+	data->args.pages  = data->pagevec;
+	data->args.count  = count;
+	data->res.fattr   = &data->fattr;
+	data->res.count   = count;
+	data->res.eof     = 0;
+	data->timestamp   = jiffies;
 
 	/* N.B. Do we need to test? Never called for swapfile inode */
 	flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
diff -u --recursive --new-file linux-2.5.52/fs/nfs/nfs4xdr.c linux-2.5.52-01-nfsv4_read/fs/nfs/nfs4xdr.c
--- linux-2.5.52/fs/nfs/nfs4xdr.c	2002-11-23 04:16:55.000000000 +0100
+++ linux-2.5.52-01-nfsv4_read/fs/nfs/nfs4xdr.c	2002-12-17 15:27:29.000000000 +0100
@@ -64,8 +64,29 @@
 
 extern int			nfs_stat_to_errno(int);
 
+/* NFSv4 COMPOUND tags are only wanted for debugging purposes */
+#ifdef DEBUG
+#define NFS4_MAXTAGLEN		20
+#else
+#define NFS4_MAXTAGLEN		0
+#endif
+
+#define compound_encode_hdr_maxsz	3 + (NFS4_MAXTAGLEN >> 2)
+#define compound_decode_hdr_maxsz	2 + (NFS4_MAXTAGLEN >> 2)
+#define op_encode_hdr_maxsz	1
+#define op_decode_hdr_maxsz	2
+#define encode_putfh_maxsz	op_encode_hdr_maxsz + 1 + \
+				(NFS4_FHSIZE >> 2)
+#define decode_putfh_maxsz	op_decode_hdr_maxsz
+
 #define NFS4_enc_compound_sz	1024  /* XXX: large enough? */
 #define NFS4_dec_compound_sz	1024  /* XXX: large enough? */
+#define NFS4_enc_read_sz	compound_encode_hdr_maxsz + \
+				encode_putfh_maxsz + \
+				op_encode_hdr_maxsz + 7
+#define NFS4_dec_read_sz	compound_decode_hdr_maxsz + \
+				decode_putfh_maxsz + \
+				op_decode_hdr_maxsz + 2
 
 static struct {
 	unsigned int	mode;
@@ -131,6 +152,7 @@
 	uint32_t *p;
 
 	dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag);
+	BUG_ON(hdr->taglen > NFS4_MAXTAGLEN);
 	RESERVE_SPACE(12+XDR_QUADLEN(hdr->taglen));
 	WRITE32(hdr->taglen);
 	WRITEMEM(hdr->tag, hdr->taglen);
@@ -472,15 +494,15 @@
 }
 
 static int
-encode_putfh(struct xdr_stream *xdr, struct nfs4_putfh *putfh)
+encode_putfh(struct xdr_stream *xdr, struct nfs_fh *fh)
 {
-	int len = putfh->pf_fhandle->size;
+	int len = fh->size;
 	uint32_t *p;
 
 	RESERVE_SPACE(8 + len);
 	WRITE32(OP_PUTFH);
 	WRITE32(len);
-	WRITEMEM(putfh->pf_fhandle->data, len);
+	WRITEMEM(fh->data, len);
 
 	return 0;
 }
@@ -497,10 +519,8 @@
 }
 
 static int
-encode_read(struct xdr_stream *xdr, struct nfs4_read *read, struct rpc_rqst *req)
+encode_read(struct xdr_stream *xdr, struct nfs_readargs *args)
 {
-	struct rpc_auth	*auth = req->rq_task->tk_auth;
-	int		replen;
 	uint32_t *p;
 
 	RESERVE_SPACE(32);
@@ -509,16 +529,8 @@
 	WRITE32(0);
 	WRITE32(0);
 	WRITE32(0);
-	WRITE64(read->rd_offset);
-	WRITE32(read->rd_length);
-
-	/* set up reply iovec
-	 *    toplevel status + taglen + rescount + OP_PUTFH + status
-	 *       + OP_READ + status + eof + datalen = 9
-	 */
-	replen = (RPC_REPHDRSIZE + auth->au_rslack + 9) << 2;
-	xdr_inline_pages(&req->rq_rcv_buf, replen,
-			 read->rd_pages, read->rd_pgbase, read->rd_length);
+	WRITE64(args->offset);
+	WRITE32(args->count);
 
 	return 0;
 }
@@ -759,14 +771,11 @@
 			status = encode_open_confirm(xdr, &cp->ops[i].u.open_confirm);
 			break;
 		case OP_PUTFH:
-			status = encode_putfh(xdr, &cp->ops[i].u.putfh);
+			status = encode_putfh(xdr, cp->ops[i].u.putfh.pf_fhandle);
 			break;
 		case OP_PUTROOTFH:
 			status = encode_putrootfh(xdr);
 			break;
-		case OP_READ:
-			status = encode_read(xdr, &cp->ops[i].u.read, req);
-			break;
 		case OP_READDIR:
 			status = encode_readdir(xdr, &cp->ops[i].u.readdir, req);
 			break;
@@ -829,6 +838,37 @@
 	return status;
 }
 
+/*
+ * Encode a READ request
+ */
+static int
+nfs4_xdr_enc_read(struct rpc_rqst *req, uint32_t *p, struct nfs_readargs *args)
+{
+	struct rpc_auth	*auth = req->rq_task->tk_auth;
+	struct xdr_stream xdr;
+	struct compound_hdr hdr = {
+		.nops	= 2,
+	};
+	int replen, status;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_compound_hdr(&xdr, &hdr);
+	status = encode_putfh(&xdr, args->fh);
+	if (status)
+		goto out;
+	status = encode_read(&xdr, args);
+
+	/* set up reply iovec
+	 *    toplevel status + taglen=0 + rescount + OP_PUTFH + status
+	 *       + OP_READ + status + eof + datalen = 9
+	 */
+	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2;
+	xdr_inline_pages(&req->rq_rcv_buf, replen,
+			 args->pages, args->pgbase, args->count);
+out:
+	return status;
+}
+
 
 /*
  * START OF "GENERIC" DECODE ROUTINES.
@@ -1368,7 +1408,7 @@
 }
 
 static int
-decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_read *read)
+decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_readres *res)
 {
 	struct iovec *iov = req->rq_rvec;
 	uint32_t *p;
@@ -1382,14 +1422,6 @@
 	READ32(eof);
 	READ32(count);
 	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
-	if (iov->iov_len < hdrlen) {
-		printk(KERN_WARNING "NFS: READ reply header overflowed:"
-				"length %u > %Zu\n", hdrlen, iov->iov_len);
-		return -errno_NFSERR_IO;
-	} else if (iov->iov_len != hdrlen) {
-		dprintk("NFS: READ header is short. iovec will be shifted.\n");
-		xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
-	}
 	recvd = req->rq_received - hdrlen;
 	if (count > recvd) {
 		printk(KERN_WARNING "NFS: server cheating in read reply: "
@@ -1397,9 +1429,9 @@
 		count = recvd;
 		eof = 0;
 	}
-	if (read->rd_eof)
-		*read->rd_eof = eof;
-	*read->rd_bytes_read = count;
+	xdr_read_pages(xdr, count);
+	res->eof = eof;
+	res->count = count;
 	return 0;
 }
 
@@ -1421,17 +1453,10 @@
 	COPYMEM(readdir->rd_resp_verifier, 8);
 
 	hdrlen = (char *) p - (char *) iov->iov_base;
-	if (iov->iov_len < hdrlen) {
-		printk(KERN_WARNING "NFS: READDIR reply header overflowed:"
-				"length %d > %Zu\n", hdrlen, iov->iov_len);
-		return -EIO;
-	} else if (iov->iov_len != hdrlen) {
-		dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
-		xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
-	}
 	recvd = req->rq_received - hdrlen;
 	if (pglen > recvd)
 		pglen = recvd;
+	xdr_read_pages(xdr, pglen);
 
 	BUG_ON(pglen + readdir->rd_pgbase > PAGE_CACHE_SIZE);
 	p   = (uint32_t *) kmap(page);
@@ -1731,9 +1756,6 @@
 		case OP_PUTROOTFH:
 			status = decode_putrootfh(xdr);
 			break;
-		case OP_READ:
-			status = decode_read(xdr, req, &op->u.read);
-			break;
 		case OP_READDIR:
 			status = decode_readdir(xdr, req, &op->u.readdir);
 			break;
@@ -1802,6 +1824,30 @@
 	return status;
 }
 
+/*
+ * Decode Read response
+ */
+static int
+nfs4_xdr_dec_read(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_readres *res)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr;
+	int status;
+
+	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+	status = decode_compound_hdr(&xdr, &hdr);
+	if (status)
+		goto out;
+	status = decode_putfh(&xdr);
+	if (status)
+		goto out;
+	status = decode_read(&xdr, rqstp, res);
+	if (!status)
+		status = -nfs_stat_to_errno(hdr.status);
+out:
+	return status;
+}
+
 uint32_t *
 nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
 {
@@ -1854,6 +1900,7 @@
 
 struct rpc_procinfo	nfs4_procedures[] = {
   PROC(COMPOUND,	enc_compound,	dec_compound),
+  PROC(READ,		enc_read,	dec_read),
 };
 
 struct rpc_version		nfs_version4 = {
diff -u --recursive --new-file linux-2.5.52/fs/nfs/proc.c linux-2.5.52-01-nfsv4_read/fs/nfs/proc.c
--- linux-2.5.52/fs/nfs/proc.c	2002-11-13 15:57:48.000000000 +0100
+++ linux-2.5.52-01-nfsv4_read/fs/nfs/proc.c	2002-12-17 15:27:29.000000000 +0100
@@ -521,13 +521,6 @@
 extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
 
 static void
-nfs_read_done(struct rpc_task *task)
-{
-	struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
-	nfs_readpage_result(task, data->u.v3.res.count, data->u.v3.res.eof);
-}
-
-static void
 nfs_proc_read_setup(struct nfs_read_data *data, unsigned int count)
 {
 	struct rpc_task		*task = &data->task;
@@ -536,26 +529,26 @@
 	int			flags;
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs_procedures[NFSPROC_READ],
-		.rpc_argp	= &data->u.v3.args,
-		.rpc_resp	= &data->u.v3.res,
+		.rpc_argp	= &data->args,
+		.rpc_resp	= &data->res,
 		.rpc_cred	= data->cred,
 	};
 	
 	req = nfs_list_entry(data->pages.next);
-	data->u.v3.args.fh     = NFS_FH(inode);
-	data->u.v3.args.offset = req_offset(req) + req->wb_offset;
-	data->u.v3.args.pgbase = req->wb_offset;
-	data->u.v3.args.pages  = data->pagevec;
-	data->u.v3.args.count  = count;
-	data->u.v3.res.fattr   = &data->fattr;
-	data->u.v3.res.count   = count;
-	data->u.v3.res.eof     = 0;
+	data->args.fh     = NFS_FH(inode);
+	data->args.offset = req_offset(req) + req->wb_offset;
+	data->args.pgbase = req->wb_offset;
+	data->args.pages  = data->pagevec;
+	data->args.count  = count;
+	data->res.fattr   = &data->fattr;
+	data->res.count   = count;
+	data->res.eof     = 0;
 	
 	/* N.B. Do we need to test? Never called for swapfile inode */
 	flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs_read_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), nfs_readpage_result, flags);
 	task->tk_calldata = data;
 	/* Release requests */
 	task->tk_release = nfs_readdata_release;
diff -u --recursive --new-file linux-2.5.52/fs/nfs/read.c linux-2.5.52-01-nfsv4_read/fs/nfs/read.c
--- linux-2.5.52/fs/nfs/read.c	2002-11-10 05:37:59.000000000 +0100
+++ linux-2.5.52-01-nfsv4_read/fs/nfs/read.c	2002-12-17 15:27:29.000000000 +0100
@@ -255,11 +255,12 @@
  * received or some error occurred (timeout or socket shutdown).
  */
 void
-nfs_readpage_result(struct rpc_task *task, unsigned int count, int eof)
+nfs_readpage_result(struct rpc_task *task)
 {
 	struct nfs_read_data	*data = (struct nfs_read_data *) task->tk_calldata;
 	struct inode		*inode = data->inode;
 	struct nfs_fattr	*fattr = &data->fattr;
+	unsigned int count = data->res.count;
 
 	dprintk("NFS: %4d nfs_readpage_result, (status %d)\n",
 		task->tk_pid, task->tk_status);
@@ -279,7 +280,7 @@
 							req->wb_bytes - count);
 				kunmap(page);
 
-				if (eof ||
+				if (data->res.eof ||
 				    ((fattr->valid & NFS_ATTR_FATTR) &&
 				     ((req_offset(req) + req->wb_offset + count) >= fattr->size)))
 					SetPageUptodate(page);
diff -u --recursive --new-file linux-2.5.52/include/linux/nfs4.h linux-2.5.52-01-nfsv4_read/include/linux/nfs4.h
--- linux-2.5.52/include/linux/nfs4.h	2002-11-23 04:16:55.000000000 +0100
+++ linux-2.5.52-01-nfsv4_read/include/linux/nfs4.h	2002-12-17 15:27:29.000000000 +0100
@@ -203,6 +203,7 @@
 enum {
 	NFSPROC4_CLNT_NULL = 0,		/* Unused */
 	NFSPROC4_CLNT_COMPOUND,		/* Soon to be unused */
+	NFSPROC4_CLNT_READ,
 };
 
 #endif
diff -u --recursive --new-file linux-2.5.52/include/linux/nfs_fs.h linux-2.5.52-01-nfsv4_read/include/linux/nfs_fs.h
--- linux-2.5.52/include/linux/nfs_fs.h	2002-12-14 18:42:09.000000000 +0100
+++ linux-2.5.52-01-nfsv4_read/include/linux/nfs_fs.h	2002-12-17 15:27:29.000000000 +0100
@@ -369,7 +369,7 @@
 extern int  nfs_readpages(struct file *, struct address_space *,
 		struct list_head *, unsigned);
 extern int  nfs_pagein_list(struct list_head *, int);
-extern void nfs_readpage_result(struct rpc_task *, unsigned int count, int eof);
+extern void nfs_readpage_result(struct rpc_task *);
 extern void nfs_readdata_release(struct rpc_task *);
 
 /*
diff -u --recursive --new-file linux-2.5.52/include/linux/nfs_xdr.h linux-2.5.52-01-nfsv4_read/include/linux/nfs_xdr.h
--- linux-2.5.52/include/linux/nfs_xdr.h	2002-11-23 04:16:55.000000000 +0100
+++ linux-2.5.52-01-nfsv4_read/include/linux/nfs_xdr.h	2002-12-17 15:27:29.000000000 +0100
@@ -422,15 +422,6 @@
 	struct nfs_fh *			pf_fhandle;       /* request */
 };
 
-struct nfs4_read {
-	u64				rd_offset;        /* request */
-	u32				rd_length;        /* request */
-	u32				*rd_eof;          /* response */
-	u32				*rd_bytes_read;   /* response */
-	struct page **			rd_pages;   /* zero-copy data */
-	unsigned int			rd_pgbase;  /* zero-copy data */
-};
-
 struct nfs4_readdir {
 	u64				rd_cookie;        /* request */
 	nfs4_verifier			rd_req_verifier;  /* request */
@@ -500,7 +491,6 @@
 		struct nfs4_open	open;
 		struct nfs4_open_confirm open_confirm;
 		struct nfs4_putfh	putfh;
-		struct nfs4_read	read;
 		struct nfs4_readdir	readdir;
 		struct nfs4_readlink	readlink;
 		struct nfs4_remove	remove;
@@ -548,20 +538,11 @@
 	struct nfs_fattr	fattr;	/* fattr storage */
 	struct list_head	pages;	/* Coalesced read requests */
 	struct page		*pagevec[NFS_READ_MAXIOV];
-	union {
-		struct {
-			struct nfs_readargs args;
-			struct nfs_readres  res;
-		} v3;   /* also v2 */
+	struct nfs_readargs args;
+	struct nfs_readres  res;
 #ifdef CONFIG_NFS_V4
-		struct {
-			struct nfs4_compound  compound;
-			struct nfs4_op        ops[3];
-			u32                   res_count;
-			u32                   res_eof;
-		} v4;
+	unsigned long		timestamp;	/* For lease renewal */
 #endif
-	} u;
 };
 
 struct nfs_write_data {


-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* Re: make module_install
From: Marius Groeger @ 2002-12-17 18:12 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: Ing.Gianfranco Morandi, LinuxPPC
In-Reply-To: <20021217173744.78C63C6139@atlas.denx.de>


On Tue, 17 Dec 2002, Wolfgang Denk wrote:

> different for embedded systems: modules are  usually  only  used  for
> driver  development,  and  then you will manually load and unload the
> driver anyway. I will even go so far to say that if you need  to  run
> "depmod"  for  your embedded system you should fix your system design
> because you are doing something wrong.

Someone might use loadable modules because he doesn't want to release
his driver under the GPL. I wouldn't exactly consider this wrong.

Regards,
Marius

-----------------------------------------------------------------------------
Marius Groeger           SYSGO Real-Time Solutions AG       mgroeger@sysgo.de
Software Engineering     Embedded and Real-Time Software    www.sysgo.de
Voice: +49-6136-9948-0   Am Pfaffenstein 14                 www.osek.de
FAX:   +49-6136-9948-10  55270 Klein-Winternheim, Germany   www.elinos.com


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply

* Re: Re: [Alsa-user] fm801 driver status?
From: Takashi Iwai @ 2002-12-17 18:11 UTC (permalink / raw)
  To: Friedrich Ewaldt; +Cc: Thierry Vignaud, alsa-devel
In-Reply-To: <3DFE3DA5.4000700@gmx.de>

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

At Mon, 16 Dec 2002 21:55:01 +0100,
Friedrich Ewaldt wrote:
> 
> >especially, please check the following:
> >
> >- loading the module and unloading it immediately works?
> >
> yep. /proc/asound builds up immediately, lsmod shows snd, ... modules 
> immediately after modprobing
 
ok.

> >- the port and irq number are correct, i.e. match with the resources
> >  listed on lspci?
> >
> info from /proc/asound/cards:
> FM801-AS at 0xec00, irq 10
> 
> lspci output:
> 00:0b.0 Multimedia audio controller: Fortemedia, Inc Xwave QS3000A
> [FM801] (rev a0)
>        Subsystem: Fortemedia, Inc: Unknown device 1319
>        Flags: bus master, medium devsel, latency 40, IRQ 10
>        I/O ports at ec00 [size=128]
> 
> (IRQ 10, I/O ec00 also shown by window?)

ok, looks fine, too.
 
> >- playback (via aplay) works?  does the system hang up at the start,
> >  during the playback or at the stop?
> >
> playback works. I even hear the correct sound when I plug in headphones :-)
> The system locks when stopping playback. (If only I had infinite audio 
> files...)
 
hmm...

> >- during the playback, does the count in /proc/interrupts increases?
> >  (check with another terminal)
> >  
> >
> the count at '10' (I assume this is irq 10) increases during playback by 
> approx. 10-15 per second.
 
ok, that's normal.

> >a typical reason of such a hang up is either the wrong spinlocks,
> >unexpected infinite loops in the driver code, or the interrupt
> >storms.  if it's the interrupt storm, then it can be related with the
> >hardware, often motherboard chipset, or BIOS version.
> >or, could it be because of ACPI?  did you apply it?
> >  
> >
> I unselected ACPI before compiling the kernel. ACPI is switched off in 
> the bios. (I have only APM running as power management)
 
ok, then it shouldn't be a problem.


perhaps do you see something out in the kernel messages on console 10
(alt+f10) when the system hangs?  well, after hang up, you cannot
switch the console, but you can start aplay on a certain
console, switch with alt+f10 and wait until the playback is finished.

anyway, could you try the attached patch?

if you see something on the kernel messages such like kernel panic or
oops, we can track the point...


ciao,

Takashi

[-- Attachment #2: fm801-intr-fix.dif --]
[-- Type: application/octet-stream, Size: 1767 bytes --]

Index: alsa-kernel/pci/fm801.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/fm801.c,v
retrieving revision 1.21
diff -u -r1.21 fm801.c
--- alsa-kernel/pci/fm801.c	16 Dec 2002 11:03:47 -0000	1.21
+++ alsa-kernel/pci/fm801.c	17 Dec 2002 18:08:52 -0000
@@ -470,8 +470,11 @@
 	unsigned int tmp;
 
 	status = inw(FM801_REG(chip, IRQ_STATUS));
-	if ((status & (FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME)) == 0)
+	status &= FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME;
+	if (! status)
 		return;
+	/* ack first */
+	outw(status, FM801_REG(chip, IRQ_STATUS));
 	if (chip->pcm && (status & FM801_IRQ_PLAYBACK) && chip->playback_substream) {
 		spin_lock(&chip->reg_lock);
 		chip->ply_buf++;
@@ -483,7 +486,6 @@
 				(chip->ply_buf & 1) ?
 					FM801_REG(chip, PLY_BUF1) :
 					FM801_REG(chip, PLY_BUF2));
-		outw(FM801_IRQ_PLAYBACK, FM801_REG(chip, IRQ_STATUS));
 		spin_unlock(&chip->reg_lock);
 		snd_pcm_period_elapsed(chip->playback_substream);
 	}
@@ -498,18 +500,13 @@
 				(chip->cap_buf & 1) ?
 					FM801_REG(chip, CAP_BUF1) :
 					FM801_REG(chip, CAP_BUF2));
-		outw(FM801_IRQ_CAPTURE, FM801_REG(chip, IRQ_STATUS));
 		spin_unlock(&chip->reg_lock);
 		snd_pcm_period_elapsed(chip->capture_substream);
 	}
-	if ((status & FM801_IRQ_MPU) && chip->rmidi != NULL) {
+	if (chip->rmidi && (status & FM801_IRQ_MPU))
 		snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
-		outw(FM801_IRQ_MPU, FM801_REG(chip, IRQ_STATUS));
-	}
-	if (status & FM801_IRQ_VOLUME) {
-		/* TODO */
-		outw(FM801_IRQ_VOLUME, FM801_REG(chip, IRQ_STATUS));
-	}
+	if (status & FM801_IRQ_VOLUME)
+		;/* TODO */
 }
 
 static snd_pcm_hardware_t snd_fm801_playback =

^ permalink raw reply

* Re: Problems with CONFIG_PREEMPT
From: Jun Sun @ 2002-12-17 18:03 UTC (permalink / raw)
  To: Colin.Helliwell; +Cc: linux-mips, jsun, rml
In-Reply-To: <OF78526308.B4153FAC-ON80256C92.002B416F@zarlink.com>

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

On Tue, Dec 17, 2002 at 08:27:16AM +0000, Colin.Helliwell@Zarlink.Com wrote:
> 
> NEW_TIME_C is set. URL to the patch is:
> http://www.kernel.org/pub/linux/kernel/people/rml/preempt-kernel/v2.4/preempt-kernel-rml-2.4.19-2.patch
>

There are some bits missing.  Not sure if it is related to your problem or not.

Robert, please take the MIPS preemptible kernel update patch.

> We ultimately want to add in real-time support, such as Ingo's O(1)
> scheduler - if this is 'complete' for MIPS. 

O(1) shortens process dispatching time, usually not a big time saver
unless you have *lots* of process and/or you are doing frequent context
switches.

Another patch which is probably more important is the Ingo's breaking
selected big lock patch.  That will preemption work more effectively.

> I don't know if it would be
> better just to go for this in one hit, or if we'd need the preemption
> sorted out anyway first. 

You do have to sort them out one by one.  (Or you get them all by becoming
mvista customer. :-0)

> Or should we just go to a 2.5.x kernel instead?

We'd love to have more people bang on 2.5 MIPS *grin* ...

Jun
 

[-- Attachment #2: 021217-mips-2.4-prek-update.patch --]
[-- Type: text/plain, Size: 2511 bytes --]


Additional patch for MIPS against RML's 2.4.19-2 preemptiable kernel patch.

http://www.kernel.org/pub/linux/kernel/people/rml/preempt-kernel/v2.4/preempt-kernel-rml-2.4.19-2.patch

Jun

diff -Nru link/arch/mips/kernel/irq.c.orig link/arch/mips/kernel/irq.c
--- link/arch/mips/kernel/irq.c.orig	Tue Dec 17 09:44:29 2002
+++ link/arch/mips/kernel/irq.c	Tue Dec 17 09:44:45 2002
@@ -507,13 +507,13 @@
 		}
 
 		current->preempt_count ++;
-		sti();
+		__sti();
 		if (user_mode(regs)) {
 			schedule();
 		} else {
 			preempt_schedule();
 		}
-		cli();
+		__cli();
 	}
 #endif
 
diff -Nru link/arch/mips/kernel/time.c.orig link/arch/mips/kernel/time.c
--- link/arch/mips/kernel/time.c.orig	Mon Dec  2 16:56:03 2002
+++ link/arch/mips/kernel/time.c	Tue Dec 17 09:53:37 2002
@@ -416,6 +416,8 @@
 {
 	int cpu = smp_processor_id();
 
+	preempt_disable();
+
 	irq_enter(cpu, irq);
 	kstat.irqs[cpu][irq]++;
 
@@ -426,12 +428,34 @@
 
 	if (softirq_pending(cpu))
 		do_softirq();
+
+#if defined(CONFIG_PREEMPT)
+        while (--current->preempt_count == 0) {
+                db_assert(intr_off());
+                db_assert(!in_interrupt());
+
+                if (current->need_resched == 0) {
+                        break;
+                }
+
+                current->preempt_count ++;
+                __sti();
+                if (user_mode(regs)) {
+                        schedule();
+                } else {
+                        preempt_schedule();
+                }
+                __cli();
+        }
+#endif
 }
 
 asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs)
 {
 	int cpu = smp_processor_id();
 
+	preempt_disable();
+
 	irq_enter(cpu, irq);
 	kstat.irqs[cpu][irq]++;
 
@@ -442,6 +466,26 @@
 
 	if (softirq_pending(cpu))
 		do_softirq();
+
+#if defined(CONFIG_PREEMPT)
+	while (--current->preempt_count == 0) {
+		db_assert(intr_off());
+		db_assert(!in_interrupt());
+
+		if (current->need_resched == 0) {
+			break;
+		}
+
+		current->preempt_count ++;
+		__sti();
+		if (user_mode(regs)) {
+			schedule();
+		} else {
+			preempt_schedule();
+		}
+		__cli();
+	}
+#endif
 }
 
 /*
diff -Nru link/include/asm-mips/softirq.h.orig link/include/asm-mips/softirq.h
--- link/include/asm-mips/softirq.h.orig	Tue Dec 17 09:44:29 2002
+++ link/include/asm-mips/softirq.h	Tue Dec 17 09:54:13 2002
@@ -10,6 +10,9 @@
 #ifndef _ASM_SOFTIRQ_H
 #define _ASM_SOFTIRQ_H
 
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 

^ permalink raw reply

* Re: .reginfo and .mdebug section
From: H. J. Lu @ 2002-12-17 18:02 UTC (permalink / raw)
  To: Long Li; +Cc: linux-mips
In-Reply-To: <20021217084303.20121.qmail@web40407.mail.yahoo.com>

On Tue, Dec 17, 2002 at 12:43:03AM -0800, Long Li wrote:
> Hi, 
> 
> I have some problems after building a linux-mips cross
> compiler on Red Hat7.1. 
> 
> 1. I tried to compile some c code targetting mips4k,
> which is 32-bit ISA. However, the map file tells me
> that the compiled code are 64-bit, since the address
> are 64-bit.

Mine is 32bit.

> 
> 2. When I compiled the c code, I found in the mapfile
> that there are some sections called .reginfo and
> .mdebug. What are those sections? I would like to get
> rid of them. However, they still exists even if I
> deleted the '-g' option for gcc. Is there a way I can
> avoid the .reginfo and .mdebug sections?

Your toolchain is very old. The newer ones no longer use .mdebug.


H.J.

^ permalink raw reply

* Re: Q: i845MP/P4-M laptop support? (specific problems listed)
From: Ducrot Bruno @ 2002-12-17 18:06 UTC (permalink / raw)
  To: Simon Oosthoek; +Cc: linux-kernel
In-Reply-To: <20021216100610.GA16816@margo.student.utwente.nl>

On Mon, Dec 16, 2002 at 11:06:10AM +0100, Simon Oosthoek wrote:
> Hi all
> 
> I've been following kernel-traffic and sometimes the web-archives in search
> for some clues about support for my laptop (jewel jade 8060, specs(in dutch):
> URL:http://www.jewelnotebooks.nl/index.php?page=jade-8060)

It sound like to be actually the same as a Toshiba Satellite for me.
Interresting.  FYI, this model is made by Compal <http://www.compal.com>
which is the actual manufacturer.

> 
> I've noticed some problems and I've seen some proposals for patches and
> fixes, but I don't have a clear picture of which is fixed and by which
> patch...
> 
> The problems I have seen:
> - apm doesn't seem to work 
>   output: 
>   APM BIOS 1.2 (kernel driver 1.16)
>   AC on-line, no system battery

APM do not work with the Satellite too.  So, yes, it is very likely to be
the exact same model...

>   
>   Q: will the ACPI patches help with this?

Yes and no.  You will have to make a (little) workaround in order to get ACPI
working, due to a bug in the BIOS.

> 
> - the -ac2 patch wasn't able to boot at all (no messages), but I haven't
> tried it more than once... the intel speedstep feature would be nice to have
> though...

You could have that with ACPI.  Alternatively, you can try cpufreq.

> 
> - resource collision on PCI 00:1f.1?
>   bootmessages: PCI: Device 00:1f.1 not available because of resource collisions
> 
> - missing driver for smartmedia slot

In fact, the smartmedia slot is available as a USB device..
Just compile with SCSI support.  Under the USB menu, you have a
'USB Mass Storage support' entry.  You should then have a 
'Microtech CompactFlash/SmartMedia support'


> from "lspci -v":
> 02:06.0 System peripheral: Toshiba America Info Systems: Unknown device 0804
> (rev 02)
>         Subsystem: COMPAL Electronics Inc: Unknown device 0012
>         Flags: slow devsel, IRQ 11
>         Memory at e0000c00 (32-bit, non-prefetchable) [disabled] [size=32]
>         Capabilities: <available only to root>

This is the Firewire link.  You can try IEEE 1394, the correct driver
should be OHCI-1394.  Since I have no HW to play with that, I can not
promise anything..


A final word: if you want ACPI for this one, you should go to
http://sf.net/projects/acpi

Try the latest patch.  Alas, if your model is buggy in the BIOS, (and
I know already that it is the case, actually) you should
ask for help in acpi mailing list at acpi-devel (at) lists.sourceforge.net
or ask me privately (but at ducrot (at) poupinou.org with a subject
containing ACPI please).

Cheers,

-- 
Ducrot Bruno
http://www.poupinou.org        Page profaissionelle
http://toto.tu-me-saoules.com  Haume page

^ permalink raw reply

* Re: dosemu 1.1.3.9 user report
From: Jan Willem Stumpel @ 2002-12-17 17:58 UTC (permalink / raw)
  To: linux-msdos

Stas Sergeev wrote:

> Nope... The fact that you got any sound at all from Duke3D
> without an immediate hang, is something very unusual. To get a
> sound from Duke3D and no hangs, this patch is a mandatory:
> http://dosemu.sourceforge.net/stas/dpmi_sti4a.diff Also read
> the comments about an adjustments you have to make to
> dosemu.conf after applying it.

I did, and now it works! A voice begins to utter threatening
language as soon as I select the difficulty level, and the game
goes on. In the demo there were only shooting sounds, etc. Maybe
voice synthesis is a different kind of task than making just "sounds".

Wolf3D still hangs at the start screen, however. At the bottom
right it says V1.1.

> Also please produce a log of a sound events (-D9+S) and mail it
> to me compressed, and maybe I'll see the problem.

I'll do that (as soon as I've found out how).

Regards, Jan



^ permalink raw reply

* Re: Compile warnings due to missing __inline__ in fs/xfs/xfs_log.h
From: Stephen Lord @ 2002-12-17 17:55 UTC (permalink / raw)
  To: Thomas Schlichter; +Cc: Linux Kernel Mailing List
In-Reply-To: <1040140891.3dff4a5bcf8f5@rumms.uni-mannheim.de>

On Tue, 2002-12-17 at 10:01, Thomas Schlichter wrote:
> As the __inline__ directive in front of the _lsn_cmp function is not used with
> the gcc version 2.95.x, compile-warnings result from many files including this
> header-file.
> 
> Is there any reason why this function is not inlined with these compiler
> versions? As I used following patch and compiled the kernel with my
> gcc2.95.3(SuSE) and an other gcc2.95.4(Debian) these compiler warnings
> disappeared and no additional warning or error occured...

The reason inline is turned off for this compiler version is that it
generates bad code when inlining this code. So you can have a quiet
compile, or bad code.

Steve




^ permalink raw reply

* clock mode problem [was: possible problems with rc6 aplay]
From: Martin Langer @ 2002-12-17 17:54 UTC (permalink / raw)
  To: Paul Davis; +Cc: alsa-devel
In-Reply-To: <20021216144807.8950gmx1@mx005-rz3.gmx.net>

On Mon, Dec 16, 2002 at 09:51:34AM -0500, Paul Davis wrote:
> 
> >Alsa has copied here the documented rme way, but this seems to be wrong for
> >me. I have just checked the behaviour of rme32, but I'm very sure that the
> >bigger ones are working in the same style.
> 
> well, they have a more complex setup:
> 
>       * clock mode: AutoSync, Master or Word Clock
>       * preferred source for autosync: ADAT1/2/3 or S/PDIF
>       * S/PDIF sample rate
>       * ADAT sample rate
>       * system sample rate (the one the master clock runs at)
> 
> so its really not possible to define "the rate" in a straightforward
> way. but i see your point.
> 

Hmm, it's more complex, but it looks not so different. 

So, I will show you another corner of this problem.

Like every rme card you have to set the rate of your output with 2 or 3
bits. The funny thing is, they never talked about the zero position. I've
tried out this with my rme32 and it is the slave clock position. Let's call
it "switch off the internal master clock".

The datasheet is just talking about one specific Master Clock Bit and not
about zeroing the sample rate bits, if you want to use slave mode. Right?

A practical experiment: If you are in slave clock mode and you are changing
the input sample rate, the output doesn't follow automatically. But if
you've set the sample rate bits for output to 0-0 before, the output rate
will change on each input change (like it should be in a perfect slave mode).

And if you want to change from slave to master clock you have to set a
sample rate different from 0-0 again. So it is only possible to switch
between this clockmodes if you are setting the sample rate and the result is
a list of master modes with sample rate dependency.

output rate bits      Master/Slave bit	Mode    	    	 
0-0  	    	      Slave	   	Slave mode
0-1		      Master		Master mode (freq. #1)
1-0		      Master		Master mode (freq. #2)
...

Everything is without warranty, but I'm very sure that this is typical for
all other rme cards: rme96, rme9652, hdsp. But I've no possibility to check
it.


martin


-- 
"2b|!2b"


-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/

^ permalink raw reply

* Re: [LARTC] what these packets means ?
From: Martin A. Brown @ 2002-12-17 17:54 UTC (permalink / raw)
  To: lartc
In-Reply-To: <marc-lartc-104014726501401@msgid-missing>


Arindam,

These are part of spanning tree protocol (STP) used in bridging (or
bridged) environments.

You must be using a bridge on your network.

-Martin

 : hi all,
 : what the folowwing tcpdump messages mean ??...
 : 802.1d--does this packet related to wireless ??
 :
 : 23:11:47.946515 0:40:96:51:ef:74 1:80:c2:0:0:0 0026 60: 802.1d config
 : 8000.00:40:96:51:ef:74.8001 root 8000.00:40:96:51:ef:74 pathcost 0 age 0
 : max 20 hello 2 fdelay 15
 : 23:11:49.948042 0:40:96:51:ef:74 1:80:c2:0:0:0 0026 60: 802.1d config
 : 8000.00:40:96:51:ef:74.8001 root 8000.00:40:96:51:ef:74 pathcost 0 age 0
 : max 20 hello 2 fdelay 15
 :
 : thanking in advance...
 : A.H
 :
 : _______________________________________________
 : LARTC mailing list / LARTC@mailman.ds9a.nl
 : http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
 :

-- 
Martin A. Brown --- SecurePipe, Inc. --- mabrown@securepipe.com

_______________________________________________
LARTC mailing list / LARTC@mailman.ds9a.nl
http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/

^ permalink raw reply

* [LARTC] what these packets means ?
From: Arindam Haldar @ 2002-12-17 17:54 UTC (permalink / raw)
  To: lartc

hi all,

what the folowwing tcpdump messages mean ??...

802.1d--does this packet related to wireless ??

23:11:47.946515 0:40:96:51:ef:74 1:80:c2:0:0:0 0026 60: 802.1d config 
8000.00:40:96:51:ef:74.8001 root 8000.00:40:96:51:ef:74 pathcost 0 age 0 
max 20 hello 2 fdelay 15
23:11:49.948042 0:40:96:51:ef:74 1:80:c2:0:0:0 0026 60: 802.1d config 
8000.00:40:96:51:ef:74.8001 root 8000.00:40:96:51:ef:74 pathcost 0 age 0 
max 20 hello 2 fdelay 15

thanking in advance...
A.H

_______________________________________________
LARTC mailing list / LARTC@mailman.ds9a.nl
http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/

^ permalink raw reply

* Re: Intel P6 vs P7 system call performance
From: Linus Torvalds @ 2002-12-17 18:01 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Dave Jones, Ingo Molnar, linux-kernel, hpa
In-Reply-To: <3DFF6501.3080106@redhat.com>



On Tue, 17 Dec 2002, Ulrich Drepper wrote:
>
> If you don't like the process-global page thingy (anymore) the
> alternative would be a sysconf() system call.

Well, we do _have_ the process-global thingy now - it's the vsyscall page.
It's not settable by the process, but it's useful for information.
Together with an elf AT_ entry pointing to it, it's certainly sufficient
for this usage, and it should also be sufficient for "future use" (ie we
can add future system information in the page later: bitmaps of features
at offset "start + 128" for example).

		Linus


^ permalink raw reply

* Re: Intel P6 vs P7 system call performance
From: Ulrich Drepper @ 2002-12-17 17:55 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Dave Jones, Ingo Molnar, linux-kernel, hpa
In-Reply-To: <Pine.LNX.4.44.0212170858510.2702-100000@home.transmeta.com>

Linus Torvalds wrote:

> Yeah, it's not very convenient. I didn't find any real alternatives,
> though, and you can always just put 0xfffff000 in memory or registers and
> jump to that.

Putting the value into memory myself is not possible.  In a DSO I have
to address memory indirectly.  But all registers (except %ebp, and maybe
it'll be used some day) are used at the time of the call.

But there is a way: if I'm using

   #define makesyscall(name) \
        movl $__NR_##name, $eax; \
        call 0xfffff000-__NR_##name($eax)

and you'd put at address 0xfffff000 the address of the entry point the
wrappers wouldn't have any problems finding it.


> In fact, I suspect that if you actually want to use it in
> glibc, then at least in the short term that's what you need to do anyway,
> sinc eyou probably don't want to have a glibc that only works with very
> recent kernels.

That's a compilation option.  We might want to do dynamic testing and
yes, a simple pointer indirection is adequate.

But still, the problem is detecting the capable kernels.  You have said
not long ago that comparing kernel versions is wrong.  And I agree.  It
doesn't cover backports and nothing.  But there is a lack of an alternative.

If you don't like the process-global page thingy (anymore) the
alternative would be a sysconf() system call.

-- 
--------------.                        ,-.            444 Castro Street
Ulrich Drepper \    ,-----------------'   \ Mountain View, CA 94041 USA
Red Hat         `--' drepper at redhat.com `---------------------------


^ permalink raw reply

* Re: Intel P6 vs P7 system call performance
From: Linus Torvalds @ 2002-12-17 17:55 UTC (permalink / raw)
  To: Ulrich Drepper, Matti Aarnio
  Cc: Hugh Dickins, Dave Jones, Ingo Molnar, linux-kernel, hpa
In-Reply-To: <20021217171908.GY32122@mea-ext.zmailer.org>



On Tue, 17 Dec 2002, Matti Aarnio wrote:
>
> On Tue, Dec 17, 2002 at 09:07:21AM -0800, Linus Torvalds wrote:
> > On Tue, 17 Dec 2002, Hugh Dickins wrote:
> > > I thought that last page was intentionally left invalid?
> >
> > It was. But I thought it made sense to use, as it's the only really
> > "special" page.
>
>   In couple of occasions I have caught myself from pre-decrementing
>   a char pointer which "just happened" to be NULL.
>
>   Please keep the last page, as well as a few of the first pages as
>   NULL-pointer poisons.

I think I have a good clean solution to this, that not only avoids the
need for any hard-coded address _at_all_, but also solves Uli's problem
quite cleanly.

Uli, how about I just add one ne warchitecture-specific ELF AT flag, which
is the "base of sysinfo page". Right now that page is all zeroes except
for the system call trampoline at the beginning, but we might want to add
other system information to the page in the future (it is readable, after
all).

So we'd have an AT_SYSINFO entry, that with the current implementation
would just get the value 0xfffff000. And then the glibc startup code could
easily be backwards compatible with the suggestion I had in the previous
email. Since we basically want to do an indirect jump anyway (because of
the lack of absolute jumps in the instruction set), this looks like the
natural way to do it.

That also allows the kernel to move around the SYSINFO page at will, and
even makes it possible to avoid it altogether (ie this will solve the
inevitable problems with UML - UML just wouldn't set AT_SYSINFO, so user
level just wouldn't even _try_ to use it).

With that, there's nothing "special" about the vsyscall page, and I'd just
go back to having the very last page unmapped (and have the vsyscall page
in some other fixmap location that might even depend on kernel
configuration).

Whaddaya think?

		Linus


^ permalink raw reply

* [PATCH] oprofile update for 2.5.52
From: John Levon @ 2002-12-17 17:50 UTC (permalink / raw)
  To: torvalds, linux-kernel


The below patch makes the following changes :

o headers cleanup
o remove deprecated kernel_only
o mention minimum oprofile version
o correctly initialise task_exit statistic
o remove racy debug check (wli saw this oops)
o remove pointless simple_open
o add dump functionality
o remove pessimising FASTCALL

Note that current .51 and also with this patch need to use oprofile CVS,
or here's a tarball :
http://www.movement.uklinux.net/oprofile-0.5cvs.tar.gz

Please apply

thanks
john


diff -X dontdiff -Naur linux-linus/arch/i386/oprofile/init.c linux/arch/i386/oprofile/init.c
--- linux-linus/arch/i386/oprofile/init.c	2002-12-16 03:45:18.000000000 +0000
+++ linux/arch/i386/oprofile/init.c	2002-12-16 03:44:32.000000000 +0000
@@ -7,7 +7,6 @@
  * @author John Levon <levon@movementarian.org>
  */
 
-#include <linux/kernel.h>
 #include <linux/oprofile.h>
 #include <linux/init.h>
  
diff -X dontdiff -Naur linux-linus/arch/i386/oprofile/nmi_int.c linux/arch/i386/oprofile/nmi_int.c
--- linux-linus/arch/i386/oprofile/nmi_int.c	2002-12-16 03:45:18.000000000 +0000
+++ linux/arch/i386/oprofile/nmi_int.c	2002-12-17 05:36:10.000000000 +0000
@@ -7,19 +7,13 @@
  * @author John Levon <levon@movementarian.org>
  */
 
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/notifier.h>
 #include <linux/smp.h>
 #include <linux/oprofile.h>
-#include <linux/pm.h>
-#include <linux/thread_info.h>
 #include <asm/nmi.h>
-#include <asm/ptrace.h>
 #include <asm/msr.h>
 #include <asm/apic.h>
-#include <asm/bitops.h>
-#include <asm/processor.h>
  
 #include "op_counter.h"
 #include "op_x86_model.h"
@@ -27,7 +21,6 @@
 static struct op_x86_model_spec const * model;
 static struct op_msrs cpu_msrs[NR_CPUS];
 static unsigned long saved_lvtpc[NR_CPUS];
-static unsigned long kernel_only;
  
 static int nmi_start(void);
 static void nmi_stop(void);
@@ -53,10 +46,9 @@
 }
  
  
-// FIXME: kernel_only
 static int nmi_callback(struct pt_regs * regs, int cpu)
 {
-	return (model->check_ctrs(cpu, &cpu_msrs[cpu], regs));
+	return model->check_ctrs(cpu, &cpu_msrs[cpu], regs);
 }
  
  
@@ -210,7 +202,6 @@
 		oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user); 
 	}
 
-	oprofilefs_create_ulong(sb, root, "kernel_only", &kernel_only);
 	return 0;
 }
  
diff -X dontdiff -Naur linux-linus/Documentation/Changes linux/Documentation/Changes
--- linux-linus/Documentation/Changes	2002-12-16 03:58:39.000000000 +0000
+++ linux/Documentation/Changes	2002-12-16 03:57:39.000000000 +0000
@@ -61,6 +61,7 @@
 o  PPP                    2.4.0                   # pppd --version
 o  isdn4k-utils           3.1pre1                 # isdnctrl 2>&1|grep version
 o  procps                 2.0.9                   # ps --version
+o  oprofile               0.5                     # oprofiled --version
 
 Kernel compilation
 ==================
@@ -368,6 +369,10 @@
 ---------
 o  <ftp://ftp.inr.ac.ru/ip-routing/iproute2-2.2.4-now-ss991023.tar.gz>
 
+OProfile
+--------
+o  <http://oprofile.sf.net/download.php3>
+ 
 Suggestions and corrections
 ===========================
 
diff -X dontdiff -Naur linux-linus/drivers/oprofile/buffer_sync.c linux/drivers/oprofile/buffer_sync.c
--- linux-linus/drivers/oprofile/buffer_sync.c	2002-12-16 03:54:20.000000000 +0000
+++ linux/drivers/oprofile/buffer_sync.c	2002-12-16 03:53:07.000000000 +0000
@@ -19,17 +19,17 @@
  * objects.
  */
 
-#include <linux/fs.h>
 #include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/dcookies.h>
+#include <linux/workqueue.h>
 #include <linux/notifier.h>
+#include <linux/dcookies.h>
 #include <linux/profile.h>
-#include <linux/workqueue.h>
-
+#include <linux/fs.h>
+ 
+#include "oprofile_stats.h"
 #include "event_buffer.h"
 #include "cpu_buffer.h"
-#include "oprofile_stats.h"
+#include "buffer_sync.h"
  
 #define DEFAULT_EXPIRE (HZ / 4)
  
diff -X dontdiff -Naur linux-linus/drivers/oprofile/cpu_buffer.c linux/drivers/oprofile/cpu_buffer.c
--- linux-linus/drivers/oprofile/cpu_buffer.c	2002-12-16 03:54:21.000000000 +0000
+++ linux/drivers/oprofile/cpu_buffer.c	2002-12-17 16:59:03.000000000 +0000
@@ -19,13 +19,10 @@
 
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
-#include <linux/smp.h>
 #include <linux/errno.h>
-#include <linux/cache.h>
  
 #include "cpu_buffer.h"
 #include "oprof.h"
-#include "oprofile_stats.h"
 
 struct oprofile_cpu_buffer cpu_buffer[NR_CPUS] __cacheline_aligned;
 
@@ -68,6 +65,7 @@
 		b->sample_received = 0;
 		b->sample_lost_locked = 0;
 		b->sample_lost_overflow = 0;
+		b->sample_lost_task_exit = 0;
 	}
 	return 0;
 fail:
@@ -92,9 +90,6 @@
 	struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[cpu];
 	struct task_struct * task;
 
-	/* temporary ? */
-	BUG_ON(!oprofile_started);
- 
 	cpu_buf->sample_received++;
  
 	if (!spin_trylock(&cpu_buf->int_lock)) {
diff -X dontdiff -Naur linux-linus/drivers/oprofile/event_buffer.c linux/drivers/oprofile/event_buffer.c
--- linux-linus/drivers/oprofile/event_buffer.c	2002-12-16 03:54:21.000000000 +0000
+++ linux/drivers/oprofile/event_buffer.c	2002-12-16 03:53:07.000000000 +0000
@@ -12,19 +12,15 @@
  * escape value ESCAPE_CODE followed by an identifying code.
  */
 
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
 #include <linux/vmalloc.h>
-#include <linux/smp.h>
-#include <linux/dcookies.h>
 #include <linux/oprofile.h>
+#include <linux/sched.h>
+#include <linux/dcookies.h>
+#include <linux/fs.h>
 #include <asm/uaccess.h>
-#include <asm/atomic.h>
-
-#include "event_buffer.h"
-#include "cpu_buffer.h"
+ 
 #include "oprof.h"
+#include "event_buffer.h"
 #include "oprofile_stats.h"
 
 DECLARE_MUTEX(buffer_sem);
diff -X dontdiff -Naur linux-linus/drivers/oprofile/event_buffer.h linux/drivers/oprofile/event_buffer.h
--- linux-linus/drivers/oprofile/event_buffer.h	2002-12-16 03:54:21.000000000 +0000
+++ linux/drivers/oprofile/event_buffer.h	2002-12-16 03:53:07.000000000 +0000
@@ -11,7 +11,7 @@
 #define EVENT_BUFFER_H
 
 #include <linux/types.h> 
-#include <linux/sem.h>
+#include <asm/semaphore.h>
  
 int alloc_event_buffer(void);
 
diff -X dontdiff -Naur linux-linus/drivers/oprofile/oprof.c linux/drivers/oprofile/oprof.c
--- linux-linus/drivers/oprofile/oprof.c	2002-12-16 03:54:21.000000000 +0000
+++ linux/drivers/oprofile/oprof.c	2002-12-17 17:23:18.000000000 +0000
@@ -10,12 +10,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/notifier.h>
-#include <linux/profile.h>
 #include <linux/oprofile.h>
+#include <asm/semaphore.h>
 
 #include "oprof.h"
 #include "event_buffer.h"
@@ -86,6 +82,7 @@
 		goto out;
 
 	oprofile_started = 1;
+ 
 	oprofile_reset_stats();
 out:
 	up(&start_sem); 
@@ -148,6 +145,10 @@
 	oprofilefs_unregister();
 }
 
-MODULE_LICENSE("GPL");
+ 
 module_init(oprofile_init);
 module_exit(oprofile_exit);
+ 
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Levon <levon@movementarian.org>");
+MODULE_DESCRIPTION("OProfile system profiler");
diff -X dontdiff -Naur linux-linus/drivers/oprofile/oprof.h linux/drivers/oprofile/oprof.h
--- linux-linus/drivers/oprofile/oprof.h	2002-12-16 03:54:21.000000000 +0000
+++ linux/drivers/oprofile/oprof.h	2002-12-17 17:00:08.000000000 +0000
@@ -10,9 +10,6 @@
 #ifndef OPROF_H
 #define OPROF_H
 
-#include <linux/spinlock.h>
-#include <linux/oprofile.h>
- 
 int oprofile_setup(void);
 void oprofile_shutdown(void); 
 
@@ -22,6 +19,8 @@
 int oprofile_start(void);
 void oprofile_stop(void);
 
+struct oprofile_operations;
+ 
 extern unsigned long fs_buffer_size;
 extern unsigned long fs_cpu_buffer_size;
 extern unsigned long fs_buffer_watershed;
@@ -29,6 +28,9 @@
 extern struct oprofile_operations * oprofile_ops;
 extern unsigned long oprofile_started;
  
+struct super_block;
+struct dentry;
+
 void oprofile_create_files(struct super_block * sb, struct dentry * root);
  
 #endif /* OPROF_H */
diff -X dontdiff -Naur linux-linus/drivers/oprofile/oprofile_files.c linux/drivers/oprofile/oprofile_files.c
--- linux-linus/drivers/oprofile/oprofile_files.c	2002-12-16 03:54:21.000000000 +0000
+++ linux/drivers/oprofile/oprofile_files.c	2002-12-17 17:23:07.000000000 +0000
@@ -7,26 +7,18 @@
  * @author John Levon <levon@movementarian.org>
  */
 
-#include <linux/oprofile.h>
 #include <linux/fs.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
- 
-#include "oprof.h"
+#include <linux/oprofile.h>
+
 #include "event_buffer.h"
 #include "oprofile_stats.h"
+#include "oprof.h"
  
 unsigned long fs_buffer_size = 131072;
 unsigned long fs_cpu_buffer_size = 8192;
 unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
 
  
-static int simple_open(struct inode * inode, struct file * filp)
-{
-	return 0;
-}
-
-
 static ssize_t cpu_type_read(struct file * file, char * buf, size_t count, loff_t * offset)
 {
 	unsigned long cpu_type = oprofile_cpu_type;
@@ -36,7 +28,6 @@
  
  
 static struct file_operations cpu_type_fops = {
-	.open		= simple_open,
 	.read		= cpu_type_read,
 };
  
@@ -71,15 +62,26 @@
 
  
 static struct file_operations enable_fops = {
-	.open		= simple_open,
 	.read		= enable_read,
 	.write		= enable_write,
 };
 
+
+static ssize_t dump_write(struct file *file, char const * buf, size_t count, loff_t * offset)
+{
+	wake_up_buffer_waiter();
+	return count;
+}
+
+
+static struct file_operations dump_fops = {
+	.write		= dump_write,
+};
  
 void oprofile_create_files(struct super_block * sb, struct dentry * root)
 {
 	oprofilefs_create_file(sb, root, "enable", &enable_fops);
+	oprofilefs_create_file(sb, root, "dump", &dump_fops);
 	oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
 	oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
 	oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
diff -X dontdiff -Naur linux-linus/drivers/oprofile/oprofilefs.c linux/drivers/oprofile/oprofilefs.c
--- linux-linus/drivers/oprofile/oprofilefs.c	2002-12-16 03:54:21.000000000 +0000
+++ linux/drivers/oprofile/oprofilefs.c	2002-12-16 03:53:08.000000000 +0000
@@ -12,12 +12,9 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/pagemap.h>
-#include <linux/fs.h>
-#include <linux/dcache.h>
-#include <linux/file.h>
-#include <linux/namei.h>
 #include <linux/oprofile.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
 #include <asm/uaccess.h>
 
 #include "oprof.h"
diff -X dontdiff -Naur linux-linus/include/linux/oprofile.h linux/include/linux/oprofile.h
--- linux-linus/include/linux/oprofile.h	2002-12-16 03:55:21.000000000 +0000
+++ linux/include/linux/oprofile.h	2002-12-16 03:54:18.000000000 +0000
@@ -55,7 +55,7 @@
  * Add a sample. This may be called from any context. Pass
  * smp_processor_id() as cpu.
  */
-extern void FASTCALL(oprofile_add_sample(unsigned long eip, unsigned long event, int cpu));
+extern void oprofile_add_sample(unsigned long eip, unsigned long event, int cpu);
 
 /**
  * Create a file of the given name as a child of the given root, with

^ permalink raw reply

* Re: 2.5.52-mjb1 (scalability / NUMA patchset)
From: William Lee Irwin III @ 2002-12-17 17:49 UTC (permalink / raw)
  To: Martin J. Bligh; +Cc: linux-kernel, gh
In-Reply-To: <568990000.1040112629@titus>

On Tue, Dec 17, 2002 at 12:10:29AM -0800, Martin J. Bligh wrote:
> The patchset contains mainly scalability and NUMA stuff, and
> anything else that stops things from irritating me. It's meant
> to be pretty stable, not so much a testing ground for new stuff.
> I'd be very interested in feedback from other people running
> large SMP or NUMA boxes.
> http://www.aracnet.com/~fletch/linux/2.5.52/patch-2.5.52-mjb1.bz2


pfn_to_nid() got lots of icache misses. Try using a macro.

 arch/i386/kernel/i386_ksyms.c |    1 -
 arch/i386/kernel/numaq.c      |   15 ++-------------
 include/asm-i386/numaq.h      |    3 ++-
 3 files changed, 4 insertions(+), 15 deletions(-)


diff -urpN linux-2.5.52-mm1/arch/i386/kernel/i386_ksyms.c mm1-2.5.52-1/arch/i386/kernel/i386_ksyms.c
--- linux-2.5.52-mm1/arch/i386/kernel/i386_ksyms.c	2002-12-16 19:29:45.000000000 -0800
+++ mm1-2.5.52-1/arch/i386/kernel/i386_ksyms.c	2002-12-17 08:47:25.000000000 -0800
@@ -67,7 +67,6 @@ EXPORT_SYMBOL(EISA_bus);
 EXPORT_SYMBOL(MCA_bus);
 #ifdef CONFIG_DISCONTIGMEM
 EXPORT_SYMBOL(node_data);
-EXPORT_SYMBOL(pfn_to_nid);
 #endif
 #ifdef CONFIG_X86_NUMAQ
 EXPORT_SYMBOL(xquad_portio);
diff -urpN linux-2.5.52-mm1/arch/i386/kernel/numaq.c mm1-2.5.52-1/arch/i386/kernel/numaq.c
--- linux-2.5.52-mm1/arch/i386/kernel/numaq.c	2002-12-15 18:08:13.000000000 -0800
+++ mm1-2.5.52-1/arch/i386/kernel/numaq.c	2002-12-17 08:51:44.000000000 -0800
@@ -27,6 +27,7 @@
 #include <linux/mm.h>
 #include <linux/bootmem.h>
 #include <linux/mmzone.h>
+#include <linux/module.h>
 #include <asm/numaq.h>
 
 /* These are needed before the pgdat's are created */
@@ -82,19 +83,7 @@ static void __init smp_dump_qct(void)
  * physnode_map[8- ] = -1;
  */
 int physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1};
-
-#define PFN_TO_ELEMENT(pfn) (pfn / PAGES_PER_ELEMENT)
-#define PA_TO_ELEMENT(pa) (PFN_TO_ELEMENT(pa >> PAGE_SHIFT))
-
-int pfn_to_nid(unsigned long pfn)
-{
-	int nid = physnode_map[PFN_TO_ELEMENT(pfn)];
-
-	if (nid == -1)
-		BUG(); /* address is not present */
-
-	return nid;
-}
+EXPORT_SYMBOL(physnode_map);
 
 /*
  * for each node mark the regions
diff -urpN linux-2.5.52-mm1/include/asm-i386/numaq.h mm1-2.5.52-1/include/asm-i386/numaq.h
--- linux-2.5.52-mm1/include/asm-i386/numaq.h	2002-12-15 18:08:09.000000000 -0800
+++ mm1-2.5.52-1/include/asm-i386/numaq.h	2002-12-17 08:45:19.000000000 -0800
@@ -38,10 +38,11 @@
 #define MAX_ELEMENTS 256
 #define PAGES_PER_ELEMENT (16777216/256)
 
+extern int physnode_map[];
+#define pfn_to_nid(pfn)	({ physnode_map[(pfn) / PAGES_PER_ELEMENT]; })
 #define pfn_to_pgdat(pfn) NODE_DATA(pfn_to_nid(pfn))
 #define PHYSADDR_TO_NID(pa) pfn_to_nid(pa >> PAGE_SHIFT)
 #define MAX_NUMNODES		8
-extern int pfn_to_nid(unsigned long);
 extern void get_memcfg_numaq(void);
 #define get_memcfg_numa() get_memcfg_numaq()
 

^ permalink raw reply

* Re: 2.5.52-mm1 DCU_MISS_OUTSTANDING + IFU_FETCH_MISS
From: William Lee Irwin III @ 2002-12-17 17:49 UTC (permalink / raw)
  To: linux-kernel
In-Reply-To: <20021217064948.GS2690@holomorphy.com>

On Mon, Dec 16, 2002 at 10:49:48PM -0800, William Lee Irwin III wrote:
> IFU_IFETCH_MISS:
> c013233c 13       1.62703     find_get_page
> c0116b00 14       1.75219     pfn_to_nid
> c0119c14 14       1.75219     kmap_atomic
> c013e7e0 15       1.87735     pte_try_to_share
> c01463f0 19       2.37797     page_add_rmap
> c01412d0 20       2.50313     do_anonymous_page
> c0141aa0 22       2.75344     handle_mm_fault
> c01416f0 24       3.00375     do_no_page
> c015c904 25       3.12891     link_path_walk
> c0117350 27       3.37922     do_page_fault

Inlining pfn_to_nid() yields:

c013e420 9        1.53846     pte_try_to_share
c0132e6c 10       1.7094      filemap_nopage
c0145850 10       1.7094      page_add_rmap
c0133658 13       2.22222     generic_file_aio_write_nolock
c01352d8 14       2.39316     buffered_rmqueue
c0140e40 17       2.90598     do_no_page
c0140b50 18       3.07692     do_anonymous_page
c01411bc 18       3.07692     handle_mm_fault
c011a820 19       3.24786     scheduler_tick
c01172d0 21       3.58974     do_page_fault

Looks good to me. No obvious difference in compile time, though.

Bill

^ permalink raw reply

* [2.5.52, afs, modules] error loading kafs.ko
From: Jochen Hein @ 2002-12-17 17:28 UTC (permalink / raw)
  To: linux-kernel


Loading the module gives:

root@gswi1164:~# modprobe kafs
Parameter rootcell length must be 1-1 characters
kafs: `jochen.org:192.168.30.202' invalid for parameter `rootcell'
FATAL: Error inserting kafs
(/lib/modules/2.5.52/kernel/fs/afs/kafs.ko): Invalid argument

The parameter is declared in fs/afs/cell.c:

cell.c:MODULE_PARM(rootcell,"s");
cell.c:MODULE_PARM_DESC(rootcell,"root AFS cell name and VL server IP addr list");

Jochen

-- 
Wenn Du nicht weißt was Du tust, tu's mit Eleganz.

^ permalink raw reply


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.