| To: | Stephane Doyon <sdoyon@xxxxxxxxx> |
|---|---|
| Subject: | Re: Long sleep with i_mutex in xfs_flush_device(), affects NFS service |
| From: | Shailendra Tripathi <stripathi@xxxxxxxxx> |
| Date: | Wed, 27 Sep 2006 17:03:31 +0530 |
| Cc: | xfs@xxxxxxxxxxx, nfs@xxxxxxxxxxxxxxxxxxxxx |
| In-reply-to: | <Pine.LNX.4.64.0609191533240.25914@madrid.max-t.internal> |
| References: | <Pine.LNX.4.64.0609191533240.25914@madrid.max-t.internal> |
| Sender: | xfs-bounce@xxxxxxxxxxx |
| User-agent: | Mozilla Thunderbird 0.9 (X11/20041127) |
Hi Stephane,
When the file system becomes nearly full, we eventually call down to xfs_flush_device(), which sleeps for 0.5seconds, waiting for xfssyncd to do some work. xfs_flush_space()does
2. xfs_flush_device is a big operation. It has to flush all the dirty pages possibly in the cache on the device. Depending upon the device, it might take significant amount of time. Keeping view of it, 500 ms in that unreasonable. Also, perhaps you would never want more than one request to be queued for device flush. 3. The hope is that after one big flush operation, it would be able to free up resources which are in transient state (over-reservation of blocks, delalloc, pending removes, ...). The whole operation is intended to make sure that ENOSPC is not returned unless really required. 4. This wait could be made deterministic by waiting for the syncer thread to complete when device flush is triggered. It seems like a fairly long time to hold a mutex. And I wonder whether it's really It might not be that good even if it doesn't. This can return pre-mature ENOSPC or it can queue many xfs_flush_device requests (which can make your system dead(-slow) anyway) necessary to keep going through that again and again for every new request after we've hit NOSPC.
if (nimaps == 0) {
if (xfs_flush_space(ip, &fsynced, &ioflag))
return XFS_ERROR(ENOSPC); error = 0;
goto retry;
}xfs_flush_space:
case 2:
xfs_iunlock(ip, XFS_ILOCK_EXCL);
xfs_flush_device(ip);
xfs_ilock(ip, XFS_ILOCK_EXCL);
*fsynced = 3;
return 0;
}
return 1;lets say that you don't enqueue it for another 2 secs. Then, in next retry it would return 1 and, hence, outer if condition would return ENOSPC. Please note that for standalone XFS, the application or client mostly don't retry and, hence, it might return premature ENOSPC. You didn't notice this because, as you said, nfs client will retry in case of ENOSPC. Assuming that you don't return *fsynced = 3 (instead *fsynced = 2), the code path will loop (because of retry) and CPU itself would become busy for no good job. You might experiment by adding deterministic wait. When you enqueue, set some flag. All others who come in between just get enqueued. Once, device flush is over wake up all. If flush could free enough resources, threads will proceed ahead and return. Otherwise, another flush would be enqueued to flush what might have come since last flush. Thanks |
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| ||
| Previous by Date: | [PATCH] xfs_db ring command, Utako Kusaka |
|---|---|
| Next by Date: | Re: LVM and XFS cannot set blocksize on block device, Shailendra Tripathi |
| Previous by Thread: | Re: [NFS] Long sleep with i_mutex in xfs_flush_device(), affects NFS service, Trond Myklebust |
| Next by Thread: | PARTIAL TAKE 955274: DMAPI qa test fixes, Vlad Apostolov |
| Indexes: | [Date] [Thread] [Top] [All Lists] |