Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 316870 Details for
Bug 455408
NFS perfomance problems on s390x
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Draft Proposed patch
455408.rhel-5.5 (text/plain), 9.88 KB, created by
Peter Staubach
on 2008-09-16 18:04:11 UTC
(
hide
)
Description:
Draft Proposed patch
Filename:
MIME Type:
Creator:
Peter Staubach
Created:
2008-09-16 18:04:11 UTC
Size:
9.88 KB
patch
obsolete
>--- linux-2.6.18.i686/fs/nfs/write.c.org >+++ linux-2.6.18.i686/fs/nfs/write.c >@@ -1011,9 +1011,23 @@ static void nfs_execute_write(struct nfs > { > struct rpc_clnt *clnt = NFS_CLIENT(data->inode); > sigset_t oldset; >+struct nfs_writeargs *args; >+struct nfs_inode *nfsi; > > rpc_clnt_sigmask(clnt, &oldset); > lock_kernel(); >+args = &data->args; >+nfsi = NFS_I(data->inode); >+if (args->offset || args->count) { >+ if (args->offset != 0 && args->offset != nfsi->offset) { >+ printk("nfs_execute_write(%lu): %Lu(%Lu)/%u\n", >+ data->inode->i_ino, args->offset, >+ nfsi->offset, args->count); >+ if (args->count != NFS_SERVER(data->inode)->wsize) >+ dump_stack(); >+ } >+ nfsi->offset = args->offset + args->count; >+} > rpc_execute(&data->task); > unlock_kernel(); > rpc_clnt_sigunmask(clnt, &oldset); >@@ -1068,6 +1082,7 @@ static int nfs_flush_multi(struct inode > nbytes, offset, how); > nbytes = 0; > } >+ nfs_inc_writes_outstanding(inode); > nfs_execute_write(data); > } while (nbytes != 0); > >@@ -1119,6 +1134,7 @@ static int nfs_flush_one(struct inode *i > /* Set up the argument struct */ > nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, how); > >+ nfs_inc_writes_outstanding(inode); > nfs_execute_write(data); > return 0; > out_bad: >@@ -1143,10 +1159,12 @@ static int nfs_flush_list(struct inode * > flush_one = nfs_flush_one; > if (wsize < PAGE_CACHE_SIZE) > flush_one = nfs_flush_multi; >+#ifdef notdef > /* For single writes, FLUSH_STABLE is more efficient */ > if (npages <= wpages && npages == NFS_I(inode)->npages > && nfs_list_entry(head->next)->wb_bytes <= wsize) > how |= FLUSH_STABLE; >+#endif > > do { > nfs_coalesce_requests(head, &one_request, wpages); >@@ -1348,6 +1366,7 @@ int nfs_writeback_done(struct rpc_task * > /* Can't do anything about it except throw an error. */ > task->tk_status = -EIO; > } >+ nfs_dec_writes_outstanding(data->inode); > return 0; > } > >@@ -1496,14 +1515,19 @@ static int nfs_flush_inode(struct inode > LIST_HEAD(head); > int res; > >+ nfs_wait_on_flushing(inode); >+ > spin_lock(&nfsi->req_lock); > res = nfs_scan_dirty(inode, &head, idx_start, npages); > spin_unlock(&nfsi->req_lock); > if (res) { > int error = nfs_flush_list(inode, &head, res, how); > if (error < 0) >- return error; >+ res = error; > } >+ >+ nfs_wake_up_after_flushing(inode); >+ > return res; > } > >@@ -1534,6 +1558,8 @@ int nfs_sync_inode_wait(struct inode *in > int nocommit = how & FLUSH_NOCOMMIT; > int pages, ret; > >+ nfs_wait_on_flushing(inode); >+ > how &= ~FLUSH_NOCOMMIT; > spin_lock(&nfsi->req_lock); > do { >@@ -1567,9 +1593,35 @@ int nfs_sync_inode_wait(struct inode *in > spin_lock(&nfsi->req_lock); > } while (ret >= 0); > spin_unlock(&nfsi->req_lock); >+ >+ nfs_wake_up_after_flushing(inode); >+ > return ret; > } > >+void nfs_sync_inode_nowait(struct inode *inode, unsigned long idx_start, >+ unsigned int npages) >+{ >+ struct nfs_inode *nfsi = NFS_I(inode); >+ LIST_HEAD(head); >+ int pages, ret = 0; >+ >+ nfs_wait_on_flushing(inode); >+ >+ spin_lock(&nfsi->req_lock); >+ do { >+ pages = nfs_scan_dirty(inode, &head, idx_start, npages); >+ if (pages != 0) { >+ spin_unlock(&nfsi->req_lock); >+ ret = nfs_flush_list(inode, &head, pages, 0); >+ spin_lock(&nfsi->req_lock); >+ } >+ } while (pages && !ret); >+ spin_unlock(&nfsi->req_lock); >+ >+ nfs_wake_up_after_flushing(inode); >+} >+ > int __init nfs_init_writepagecache(void) > { > nfs_wdata_cachep = kmem_cache_create("nfs_write_data", >--- linux-2.6.18.i686/fs/nfs/inode.c.org >+++ linux-2.6.18.i686/fs/nfs/inode.c >@@ -439,6 +439,64 @@ static void nfs_wake_up_inode(struct ino > wake_up_bit(&nfsi->flags, NFS_INO_REVALIDATING); > } > >+/* >+ * Wait for the WRITE flushing to complete. >+ */ >+int nfs_wait_on_flushing(struct inode *inode) >+{ >+ struct rpc_clnt *clnt = NFS_CLIENT(inode); >+ struct nfs_inode *nfsi = NFS_I(inode); >+ sigset_t oldmask; >+ int error; >+ >+ rpc_clnt_sigmask(clnt, &oldmask); >+ error = wait_on_bit_lock(&nfsi->flags, NFS_INO_FLUSHING, >+ nfs_wait_schedule, TASK_INTERRUPTIBLE); >+ rpc_clnt_sigunmask(clnt, &oldmask); >+ >+ return error; >+} >+ >+void nfs_wake_up_after_flushing(struct inode *inode) >+{ >+ struct nfs_inode *nfsi = NFS_I(inode); >+ >+ clear_bit(NFS_INO_FLUSHING, &nfsi->flags); >+ smp_mb__after_clear_bit(); >+ wake_up_bit(&nfsi->flags, NFS_INO_FLUSHING); >+} >+ >+int nfs_max_outstanding_writes = 0; >+int nfs_peak_outstanding_writes = 0; >+ >+void nfs_inc_writes_outstanding(struct inode *inode) >+{ >+ struct nfs_inode *nfsi = NFS_I(inode); >+ int peak; >+ >+ peak = atomic_inc_return(&nfsi->writes); >+ if (peak > nfs_peak_outstanding_writes) >+ nfs_peak_outstanding_writes = peak; >+} >+ >+void nfs_dec_writes_outstanding(struct inode *inode) >+{ >+ struct nfs_inode *nfsi = NFS_I(inode); >+ >+ if (atomic_dec_return(&nfsi->writes) < nfs_max_outstanding_writes) >+ wake_up(&nfsi->writes_wq); >+} >+ >+void nfs_wait_for_writes_outstanding(struct inode *inode) >+{ >+ struct nfs_inode *nfsi = NFS_I(inode); >+ >+ if (nfs_max_outstanding_writes) { >+ wait_event(nfsi->writes_wq, >+ atomic_read(&nfsi->writes) < nfs_max_outstanding_writes); >+ } >+} >+ > int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) > { > struct inode *inode = dentry->d_inode; >@@ -1082,6 +1140,7 @@ struct inode *nfs_alloc_inode(struct sup > #ifdef CONFIG_NFS_V4 > nfsi->nfs4_acl = NULL; > #endif /* CONFIG_NFS_V4 */ >+nfsi->offset = 0; > return &nfsi->vfs_inode; > } > >@@ -1120,6 +1179,8 @@ static void init_once(void * foo, kmem_c > atomic_set(&nfsi->silly_count, 1); > INIT_HLIST_HEAD(&nfsi->silly_list); > init_waitqueue_head(&nfsi->waitqueue); >+ atomic_set(&nfsi->writes, 0); >+ init_waitqueue_head(&nfsi->writes_wq); > nfs4_init_once(nfsi); > } > } >--- linux-2.6.18.i686/fs/nfs/file.c.org >+++ linux-2.6.18.i686/fs/nfs/file.c >@@ -338,7 +338,11 @@ static void nfs_invalidate_page(struct p > static int nfs_release_page(struct page *page, gfp_t gfp) > { > if (gfp & __GFP_FS) { >+#ifdef notdef > int error = nfs_wb_page(page->mapping->host, page); >+#else >+ int error = nfs_sync_inode_wait(page->mapping->host, 0, 0, FLUSH_STABLE); >+#endif > > if (error == 0) { > nfs_fscache_release_page(page); >@@ -395,6 +399,11 @@ static int nfs_need_sync_write(struct fi > return 0; > } > >+static int nfs_is_serial(struct inode *inode, loff_t pos) >+{ >+ return NFS_I(inode)->wrpos == pos; >+} >+ > static ssize_t > nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) > { >@@ -427,13 +436,25 @@ nfs_file_write(struct kiocb *iocb, const > if (!count) > goto out; > >+ nfs_wait_for_writes_outstanding(inode); >+ > nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); > result = generic_file_aio_write(iocb, buf, count, pos); >- /* Return error values for O_SYNC and IS_SYNC() */ >- if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) { >- int err = nfs_do_fsync(iocb->ki_filp->private_data, inode); >- if (err < 0) >- result = err; >+ if (result >= 0) { >+ /* Return error values for O_SYNC and IS_SYNC() */ >+ if (nfs_need_sync_write(iocb->ki_filp, inode)) { >+ int err; >+ err = nfs_do_fsync(iocb->ki_filp->private_data, inode); >+ if (err < 0) >+ result = err; >+ } else if (nfs_is_serial(inode, pos) && >+ NFS_I(inode)->ndirty >= NFS_SERVER(inode)->wpages) { >+ filemap_fdatawrite(inode->i_mapping); >+ filemap_fdatawait(inode->i_mapping); >+ nfs_sync_inode_nowait(inode, 0, >+ NFS_SERVER(inode)->wpages); >+ } >+ NFS_I(inode)->wrpos = pos + result; > } > out: > return result; >--- linux-2.6.18.i686/fs/nfs/internal.h.org >+++ linux-2.6.18.i686/fs/nfs/internal.h >@@ -153,6 +153,8 @@ extern void nfs_clear_inode(struct inode > #ifdef CONFIG_NFS_V4 > extern void nfs4_clear_inode(struct inode *); > #endif >+extern int nfs_wait_on_flushing(struct inode *); >+extern void nfs_wake_up_after_flushing(struct inode *); > > /* super.c */ > extern struct file_system_type nfs_xdev_fs_type; >@@ -168,6 +170,12 @@ extern void __exit unregister_nfs_fs(voi > extern void nfs_sb_active(struct nfs_server *server); > extern void nfs_sb_deactive(struct nfs_server *server); > >+extern void nfs_inc_writes_outstanding(struct inode *inode); >+extern void nfs_dec_writes_outstanding(struct inode *inode); >+extern void nfs_wait_for_writes_outstanding(struct inode *inode); >+extern int nfs_max_outstanding_writes; >+extern int nfs_peak_outstanding_writes; >+ > /* namespace.c */ > extern char *nfs_path(const char *base, > const struct dentry *droot, >--- linux-2.6.18.i686/fs/nfs/sysctl.c.org >+++ linux-2.6.18.i686/fs/nfs/sysctl.c >@@ -98,6 +98,22 @@ static ctl_table nfs_cb_sysctls[] = { > .proc_handler = &proc_dointvec, > }, > #endif >+ { >+ .ctl_name = CTL_UNNUMBERED, >+ .procname = "nfs_max_outstanding_writes", >+ .data = &nfs_max_outstanding_writes, >+ .maxlen = sizeof(int), >+ .mode = 0644, >+ .proc_handler = &proc_dointvec, >+ }, >+ { >+ .ctl_name = CTL_UNNUMBERED, >+ .procname = "nfs_peak_outstanding_writes", >+ .data = &nfs_peak_outstanding_writes, >+ .maxlen = sizeof(int), >+ .mode = 0644, >+ .proc_handler = &proc_dointvec, >+ }, > { .ctl_name = 0 } > }; > >--- linux-2.6.18.i686/include/linux/nfs_fs.h.org >+++ linux-2.6.18.i686/include/linux/nfs_fs.h >@@ -203,6 +203,10 @@ struct nfs_inode { > struct fscache_cookie *fscache; > #endif > struct inode vfs_inode; >+__u64 offset; >+ atomic_t writes; /* number of outstandings WRITES */ >+ wait_queue_head_t writes_wq; >+ loff_t wrpos; /* position after the last write */ > }; > > /* >@@ -224,6 +228,7 @@ struct nfs_inode { > #define NFS_INO_ACL_LRU_SET (3) /* Inode is on the LRU list */ > #define NFS_INO_FSCACHE (4) /* inode can be cached by FS-Cache */ > #define NFS_INO_MOUNTPOINT (5) /* inode is remote mountpoint */ >+#define NFS_INO_FLUSHING (6) /* flushing WRITE requests */ > > static inline struct nfs_inode *NFS_I(struct inode *inode) > { >@@ -453,6 +458,7 @@ extern void nfs_writedata_release(void * > * return value!) > */ > extern int nfs_sync_inode_wait(struct inode *, unsigned long, unsigned int, int); >+extern void nfs_sync_inode_nowait(struct inode *, unsigned long, unsigned int); > #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) > extern int nfs_commit_inode(struct inode *, int); > extern struct nfs_write_data *nfs_commit_alloc(void);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 455408
:
311973
|
312656
|
313588
|
314535
|
316301
|
316870
|
317393