ceph: show tasks waiting on caps in debugfs caps file
diff mbox series

Message ID 20191125151732.139754-1-jlayton@kernel.org
State New
Headers show
Series
  • ceph: show tasks waiting on caps in debugfs caps file
Related show

Commit Message

Jeff Layton Nov. 25, 2019, 3:17 p.m. UTC
Display the tgid of the waiting task, plus inode number, and the
caps we need and want.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/ceph/caps.c       | 17 +++++++++++++++++
 fs/ceph/debugfs.c    | 13 +++++++++++++
 fs/ceph/mds_client.c |  1 +
 fs/ceph/mds_client.h |  9 +++++++++
 4 files changed, 40 insertions(+)

Comments

Yan, Zheng Nov. 26, 2019, 7:41 a.m. UTC | #1
On Mon, Nov 25, 2019 at 11:21 PM Jeff Layton <jlayton@kernel.org> wrote:
>
> Display the tgid of the waiting task, plus inode number, and the
> caps we need and want.
>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
>  fs/ceph/caps.c       | 17 +++++++++++++++++
>  fs/ceph/debugfs.c    | 13 +++++++++++++
>  fs/ceph/mds_client.c |  1 +
>  fs/ceph/mds_client.h |  9 +++++++++
>  4 files changed, 40 insertions(+)
>
> diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
> index f5a38910a82b..271d8283d263 100644
> --- a/fs/ceph/caps.c
> +++ b/fs/ceph/caps.c
> @@ -2764,7 +2764,19 @@ int ceph_get_caps(struct file *filp, int need, int want,
>                 if (ret == -EAGAIN)
>                         continue;
>                 if (!ret) {
> +                       struct ceph_mds_client *mdsc = fsc->mdsc;
> +                       struct cap_wait cw;
>                         DEFINE_WAIT_FUNC(wait, woken_wake_function);
> +
> +                       cw.ino = inode->i_ino;
> +                       cw.tgid = current->tgid;
> +                       cw.need = need;
> +                       cw.want = want;
> +
> +                       spin_lock(&mdsc->caps_list_lock);
> +                       list_add(&cw.list, &mdsc->cap_wait_list);
> +                       spin_unlock(&mdsc->caps_list_lock);
> +
>                         add_wait_queue(&ci->i_cap_wq, &wait);
>
>                         flags |= NON_BLOCKING;
> @@ -2778,6 +2790,11 @@ int ceph_get_caps(struct file *filp, int need, int want,
>                         }
>
>                         remove_wait_queue(&ci->i_cap_wq, &wait);
> +
> +                       spin_lock(&mdsc->caps_list_lock);
> +                       list_del(&cw.list);
> +                       spin_unlock(&mdsc->caps_list_lock);
> +
>                         if (ret == -EAGAIN)
>                                 continue;
>                 }
> diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
> index facb387c2735..c281f32b54f7 100644
> --- a/fs/ceph/debugfs.c
> +++ b/fs/ceph/debugfs.c
> @@ -139,6 +139,7 @@ static int caps_show(struct seq_file *s, void *p)
>         struct ceph_fs_client *fsc = s->private;
>         struct ceph_mds_client *mdsc = fsc->mdsc;
>         int total, avail, used, reserved, min, i;
> +       struct cap_wait *cw;
>
>         ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min);
>         seq_printf(s, "total\t\t%d\n"
> @@ -166,6 +167,18 @@ static int caps_show(struct seq_file *s, void *p)
>         }
>         mutex_unlock(&mdsc->mutex);
>
> +       seq_printf(s, "\n\nWaiters:\n--------\n");
> +       seq_printf(s, "tgid         ino                need             want\n");
> +       seq_printf(s, "-----------------------------------------------------\n");
> +
> +       spin_lock(&mdsc->caps_list_lock);
> +       list_for_each_entry(cw, &mdsc->cap_wait_list, list) {
> +               seq_printf(s, "%-13d0x%-17lx%-17s%-17s\n", cw->tgid, cw->ino,
> +                               ceph_cap_string(cw->need),
> +                               ceph_cap_string(cw->want));
> +       }
> +       spin_unlock(&mdsc->caps_list_lock);
> +
>         return 0;
>  }
>
> diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
> index 890f7f613390..40f9a640481d 100644
> --- a/fs/ceph/mds_client.c
> +++ b/fs/ceph/mds_client.c
> @@ -4169,6 +4169,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
>         INIT_DELAYED_WORK(&mdsc->delayed_work, delayed_work);
>         mdsc->last_renew_caps = jiffies;
>         INIT_LIST_HEAD(&mdsc->cap_delay_list);
> +       INIT_LIST_HEAD(&mdsc->cap_wait_list);
>         spin_lock_init(&mdsc->cap_delay_lock);
>         INIT_LIST_HEAD(&mdsc->snap_flush_list);
>         spin_lock_init(&mdsc->snap_flush_lock);
> diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
> index 5cd131b41d84..14c7e8c49970 100644
> --- a/fs/ceph/mds_client.h
> +++ b/fs/ceph/mds_client.h
> @@ -340,6 +340,14 @@ struct ceph_quotarealm_inode {
>         struct inode *inode;
>  };
>
> +struct cap_wait {
> +       struct list_head        list;
> +       unsigned long           ino;
> +       pid_t                   tgid;
> +       int                     need;
> +       int                     want;
> +};
> +
>  /*
>   * mds client state
>   */
> @@ -416,6 +424,7 @@ struct ceph_mds_client {
>         spinlock_t      caps_list_lock;
>         struct          list_head caps_list; /* unused (reserved or
>                                                 unreserved) */
> +       struct          list_head cap_wait_list;
>         int             caps_total_count;    /* total caps allocated */
>         int             caps_use_count;      /* in use */
>         int             caps_use_max;        /* max used caps */
> --
> 2.23.0
>

Reviewed-by: "Yan, Zheng" <zyan@redhat.com>

Patch
diff mbox series

diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index f5a38910a82b..271d8283d263 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2764,7 +2764,19 @@  int ceph_get_caps(struct file *filp, int need, int want,
 		if (ret == -EAGAIN)
 			continue;
 		if (!ret) {
+			struct ceph_mds_client *mdsc = fsc->mdsc;
+			struct cap_wait cw;
 			DEFINE_WAIT_FUNC(wait, woken_wake_function);
+
+			cw.ino = inode->i_ino;
+			cw.tgid = current->tgid;
+			cw.need = need;
+			cw.want = want;
+
+			spin_lock(&mdsc->caps_list_lock);
+			list_add(&cw.list, &mdsc->cap_wait_list);
+			spin_unlock(&mdsc->caps_list_lock);
+
 			add_wait_queue(&ci->i_cap_wq, &wait);
 
 			flags |= NON_BLOCKING;
@@ -2778,6 +2790,11 @@  int ceph_get_caps(struct file *filp, int need, int want,
 			}
 
 			remove_wait_queue(&ci->i_cap_wq, &wait);
+
+			spin_lock(&mdsc->caps_list_lock);
+			list_del(&cw.list);
+			spin_unlock(&mdsc->caps_list_lock);
+
 			if (ret == -EAGAIN)
 				continue;
 		}
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
index facb387c2735..c281f32b54f7 100644
--- a/fs/ceph/debugfs.c
+++ b/fs/ceph/debugfs.c
@@ -139,6 +139,7 @@  static int caps_show(struct seq_file *s, void *p)
 	struct ceph_fs_client *fsc = s->private;
 	struct ceph_mds_client *mdsc = fsc->mdsc;
 	int total, avail, used, reserved, min, i;
+	struct cap_wait	*cw;
 
 	ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min);
 	seq_printf(s, "total\t\t%d\n"
@@ -166,6 +167,18 @@  static int caps_show(struct seq_file *s, void *p)
 	}
 	mutex_unlock(&mdsc->mutex);
 
+	seq_printf(s, "\n\nWaiters:\n--------\n");
+	seq_printf(s, "tgid         ino                need             want\n");
+	seq_printf(s, "-----------------------------------------------------\n");
+
+	spin_lock(&mdsc->caps_list_lock);
+	list_for_each_entry(cw, &mdsc->cap_wait_list, list) {
+		seq_printf(s, "%-13d0x%-17lx%-17s%-17s\n", cw->tgid, cw->ino,
+				ceph_cap_string(cw->need),
+				ceph_cap_string(cw->want));
+	}
+	spin_unlock(&mdsc->caps_list_lock);
+
 	return 0;
 }
 
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 890f7f613390..40f9a640481d 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -4169,6 +4169,7 @@  int ceph_mdsc_init(struct ceph_fs_client *fsc)
 	INIT_DELAYED_WORK(&mdsc->delayed_work, delayed_work);
 	mdsc->last_renew_caps = jiffies;
 	INIT_LIST_HEAD(&mdsc->cap_delay_list);
+	INIT_LIST_HEAD(&mdsc->cap_wait_list);
 	spin_lock_init(&mdsc->cap_delay_lock);
 	INIT_LIST_HEAD(&mdsc->snap_flush_list);
 	spin_lock_init(&mdsc->snap_flush_lock);
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 5cd131b41d84..14c7e8c49970 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -340,6 +340,14 @@  struct ceph_quotarealm_inode {
 	struct inode *inode;
 };
 
+struct cap_wait {
+	struct list_head	list;
+	unsigned long		ino;
+	pid_t			tgid;
+	int			need;
+	int			want;
+};
+
 /*
  * mds client state
  */
@@ -416,6 +424,7 @@  struct ceph_mds_client {
 	spinlock_t	caps_list_lock;
 	struct		list_head caps_list; /* unused (reserved or
 						unreserved) */
+	struct		list_head cap_wait_list;
 	int		caps_total_count;    /* total caps allocated */
 	int		caps_use_count;      /* in use */
 	int		caps_use_max;	     /* max used caps */