Re: [PATCH 14/14] xfs: poll waiting for quotacheck

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jun 11, 2019 at 11:49:02PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> 
> Create a pwork destroy function that uses polling instead of
> uninterruptible sleep to wait for work items to finish so that we can
> touch the softlockup watchdog.  IOWs, gross hack.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> ---
>  fs/xfs/xfs_iwalk.c |    3 +++
>  fs/xfs/xfs_iwalk.h |    3 ++-
>  fs/xfs/xfs_pwork.c |   19 +++++++++++++++++++
>  fs/xfs/xfs_pwork.h |    3 +++
>  fs/xfs/xfs_qm.c    |    2 +-
>  5 files changed, 28 insertions(+), 2 deletions(-)
> 
> 
...
> diff --git a/fs/xfs/xfs_pwork.c b/fs/xfs/xfs_pwork.c
> index 8d0d5f130252..c2f02b710b8c 100644
> --- a/fs/xfs/xfs_pwork.c
> +++ b/fs/xfs/xfs_pwork.c
> @@ -13,6 +13,7 @@
>  #include "xfs_trace.h"
>  #include "xfs_sysctl.h"
>  #include "xfs_pwork.h"
> +#include <linux/nmi.h>
>  
>  /*
>   * Parallel Work Queue
> @@ -46,6 +47,8 @@ xfs_pwork_work(
>  	error = pctl->work_fn(pctl->mp, pwork);
>  	if (error && !pctl->error)
>  		pctl->error = error;
> +	atomic_dec(&pctl->nr_work);
> +	wake_up(&pctl->poll_wait);

We could use atomic_dec_and_test() here to avoid some unnecessary
wakeups. With that fixed up:

Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx>

>  }
>  
>  /*
> @@ -76,6 +79,8 @@ xfs_pwork_init(
>  	pctl->work_fn = work_fn;
>  	pctl->error = 0;
>  	pctl->mp = mp;
> +	atomic_set(&pctl->nr_work, 0);
> +	init_waitqueue_head(&pctl->poll_wait);
>  
>  	return 0;
>  }
> @@ -88,6 +93,7 @@ xfs_pwork_queue(
>  {
>  	INIT_WORK(&pwork->work, xfs_pwork_work);
>  	pwork->pctl = pctl;
> +	atomic_inc(&pctl->nr_work);
>  	queue_work(pctl->wq, &pwork->work);
>  }
>  
> @@ -101,6 +107,19 @@ xfs_pwork_destroy(
>  	return pctl->error;
>  }
>  
> +/*
> + * Wait for the work to finish by polling completion status and touch the soft
> + * lockup watchdog.  This is for callers such as mount which hold locks.
> + */
> +void
> +xfs_pwork_poll(
> +	struct xfs_pwork_ctl	*pctl)
> +{
> +	while (wait_event_timeout(pctl->poll_wait,
> +				atomic_read(&pctl->nr_work) == 0, HZ) == 0)
> +		touch_softlockup_watchdog();
> +}
> +
>  /*
>   * Return the amount of parallelism that the data device can handle, or 0 for
>   * no limit.
> diff --git a/fs/xfs/xfs_pwork.h b/fs/xfs/xfs_pwork.h
> index 4cf1a6f48237..ff93873df8d3 100644
> --- a/fs/xfs/xfs_pwork.h
> +++ b/fs/xfs/xfs_pwork.h
> @@ -18,6 +18,8 @@ struct xfs_pwork_ctl {
>  	struct workqueue_struct	*wq;
>  	struct xfs_mount	*mp;
>  	xfs_pwork_work_fn	work_fn;
> +	struct wait_queue_head	poll_wait;
> +	atomic_t		nr_work;
>  	int			error;
>  };
>  
> @@ -53,6 +55,7 @@ int xfs_pwork_init(struct xfs_mount *mp, struct xfs_pwork_ctl *pctl,
>  		unsigned int nr_threads);
>  void xfs_pwork_queue(struct xfs_pwork_ctl *pctl, struct xfs_pwork *pwork);
>  int xfs_pwork_destroy(struct xfs_pwork_ctl *pctl);
> +void xfs_pwork_poll(struct xfs_pwork_ctl *pctl);
>  unsigned int xfs_pwork_guess_datadev_parallelism(struct xfs_mount *mp);
>  
>  #endif /* __XFS_PWORK_H__ */
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 8004c931c86e..8bb902125403 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -1304,7 +1304,7 @@ xfs_qm_quotacheck(
>  		flags |= XFS_PQUOTA_CHKD;
>  	}
>  
> -	error = xfs_iwalk_threaded(mp, 0, xfs_qm_dqusage_adjust, 0, NULL);
> +	error = xfs_iwalk_threaded(mp, 0, xfs_qm_dqusage_adjust, 0, true, NULL);
>  	if (error)
>  		goto error_return;
>  
> 



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux