* 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
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.