Re: Stack usage
John Hughes <[email protected]>
| Newsgroups | gmane.linux.cluster.ssic.devel |
|---|---|
| Message-ID | <[email protected]> |
John Hughes wrote:
> One of the problems we have in current OpenSSI is excessive stack
> usage. This is often a problem when we use drbd for the root filesystem
> (cfs calls drbd which calls the socket layer which... runs out of stack).
>
See bug
https://sourceforge.net/tracker2/?func=detail&aid=1367582&group_id=32541&atid=405834
One coding style in OpenSSI that leads to "excessive" stack usage is:
some_cfs_func (...) {
if (for this node) {
do on this node;
}
else {
rpcargs args;
rpcret ret;
args = ...;
status = rpccall (...);
...
}
}
The problem is that the space used by the rpc args and ret is allocated on
the stack even on the path where the operation is local. This path is
often (always?) deeper (especially when drbd is being used!).
(It's a pity gcc couldn't be smarter about this!)
A "solution" may be to rework the function to look something like:
some_cfs_func (...) {
if (for this node) {
do on this node;
}
else {
status = some_cfs_func_remote ();
}
}
some_cfs_func_remote (...) {
rpcargs args;
rpcret ret;
args = ...;
status = rpccall (...);
...
}
Now the local path doesn't get the rpc args on the stack.
It's ugly though.
(E.G. for cfs_proc_rename only 44 bytes are needed on the local path as
against 472 bytes on the rpc path).
------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
ssic-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ssic-linux-devel
cluster-ssi-cfs-proc.c.patch
(text/x-patch, 3 KB)
Index: proc.c
===================================================================
RCS file: /usr/local/lib/cvs-repo/sourceforge-openssi/kernel/cluster/ssi/cfs/proc.c,v
retrieving revision 1.18
diff -u -r1.18 proc.c
--- proc.c 10 Oct 2008 08:10:32 -0000 1.18
+++ proc.c 13 Jan 2009 14:12:40 -0000
@@ -801,6 +801,13 @@
return status;
}
+
+/* Hack to reduce stack usage on local path - JH */
+static int
+cfs_proc_rename_remote(cfs_mntinfo_t *mip,
+ struct inode *old_dir, struct qstr *old_name, struct inode *oip,
+ struct inode *new_dir, struct qstr *new_name, struct inode *nip);
+
static int
cfs_proc_rename(struct inode *old_dir, struct qstr *old_name, struct inode *oip,
struct inode *new_dir, struct qstr *new_name, struct inode *nip)
@@ -839,32 +846,12 @@
HASH_RELE(nhp);
}
} else {
- struct cfsrnmres res;
- struct cfsrnmargs args;
-
- args.crna_from.cda_fhandle = *itocfh(old_dir);
- args.crna_from.cda_name = *old_name;
- args.crna_to.cda_fhandle = *itocfh(new_dir);
- args.crna_to.cda_name = *new_name;
- cfstok_get_agent(&args.crna_agent);
-
- status = rcfscall(mip, CFSD_PROC_RENAME,
- (xdrproc_t)xdr_cfsrnmargs,
- (caddr_t)&args,
- (xdrproc_t)xdr_cfsrnmres,
- (caddr_t)&res);
+ /* Handle remote case in another proc so it's large
+ stack usage doesn't eat up space for local case */
- if (!status) {
- status = res.crnmr_status;
- }
- if (!status) {
- cfs_refresh_inode(old_dir, &res.crnmr_odirattr);
- if (new_dir != old_dir)
- cfs_refresh_inode(new_dir, &res.crnmr_ndirattr);
- cfs_refresh_inode(oip, &res.crnmr_oattr);
- if (nip)
- cfs_refresh_inode(nip, &res.crnmr_nattr);
- }
+ status = cfs_proc_rename_remote(mip,
+ old_dir, old_name, oip,
+ new_dir, new_name, nip);
}
/* Ignore error, get inode due to retransmitted failover request */
@@ -881,6 +868,48 @@
return status;
}
+/*
+ * Break out the remote path from cfs_proc_rename so we reduce stack
+ * usage on the local path. Ugly. JH
+ *
+ */
+
+static int
+cfs_proc_rename_remote(cfs_mntinfo_t *mip,
+ struct inode *old_dir, struct qstr *old_name, struct inode *oip,
+ struct inode *new_dir, struct qstr *new_name, struct inode *nip)
+{
+ int status;
+
+ struct cfsrnmres res;
+ struct cfsrnmargs args;
+
+ args.crna_from.cda_fhandle = *itocfh(old_dir);
+ args.crna_from.cda_name = *old_name;
+ args.crna_to.cda_fhandle = *itocfh(new_dir);
+ args.crna_to.cda_name = *new_name;
+ cfstok_get_agent(&args.crna_agent);
+
+ status = rcfscall(mip, CFSD_PROC_RENAME,
+ (xdrproc_t)xdr_cfsrnmargs,
+ (caddr_t)&args,
+ (xdrproc_t)xdr_cfsrnmres,
+ (caddr_t)&res);
+
+ if (!status) {
+ status = res.crnmr_status;
+ }
+ if (!status) {
+ cfs_refresh_inode(old_dir, &res.crnmr_odirattr);
+ if (new_dir != old_dir)
+ cfs_refresh_inode(new_dir, &res.crnmr_ndirattr);
+ cfs_refresh_inode(oip, &res.crnmr_oattr);
+ if (nip)
+ cfs_refresh_inode(nip, &res.crnmr_nattr);
+ }
+ return status;
+}
+
static int
cfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
{