gfs2: Dump nrpages for inodes and their glocks
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 gfs2: Dump nrpages for inodes and their glocks
Hi,
This patch is based on an idea from Steve Whitehouse. The idea is to dump the number of pages (both inode and its glock's address space) in the glock dumps. To avoid adding any new locks, I switch from calling i_size_read to using its constituant pieces, namely, calling preempt_disable before gathering the values of i_size and the new nrpages values, then I preempt_enable.
--- fs/gfs2/glops.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
fs/gfs2/glops.c +16 -2
@@ -470,14 +470,28 @@ static int inode_go_lock(struct gfs2_holder *gh)static void inode_go_dump (struct seq_file *seq,const struct gfs2_glock *gl) {const struct gfs2_inode *ip = gl->gl_object; +const struct inode *inode; +const struct address_space *mapping = (const struct address_space *) + (gl +1 );/* Can't use gfs2_glock2aspace due to const */ +unsigned long nrpages1, nrpages2; +loff_t i_size; +if (ip ==NULL )return ; -gfs2_print_dbg (seq," I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu\n" , + + inode = &ip->i_inode; +preempt_disable (); + i_size = inode->i_size; + nrpages1 = inode->i_data.nrpages; + nrpages2 = mapping->nrpages; +preempt_enable (); + +gfs2_print_dbg (seq," I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu p:%lu/%lu\n" , (unsigned long long )ip->i_no_formal_ino, (unsigned long long )ip->i_no_addr,IF2DT (ip->i_inode.i_mode), ip->i_flags, (unsigned int )ip->i_diskflags, - (unsigned long long )i_size_read (&ip->i_inode)); + (unsigned long long )i_size, nrpages1, nrpages2); }/**
Andreas Gruenbacher
maintainerPATCH 1/1 gfs2: Dump nrpages for inodes and their glocks
Hi,
Quoted 19 lines · Bob Peterson
Hi,
This patch is based on an idea from Steve Whitehouse. The idea is to dump the number of pages (both inode and its glock's address space) in the glock dumps. To avoid adding any new locks, I switch from calling
i_size_readto using its constituant pieces, namely, callingpreempt_disablebefore gathering the values ofi_sizeand the new nrpages values, then Ipreempt_enable.Signed-off-by Bob Peterson <[email protected]>--- fs/gfs2/glops.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)fs/gfs2/glops.c +0
-0
fs/gfs2/glops.c static int inode_go_lock(struct gfs2_holder *gh) · line 473
Quoted 4 lines
fs/gfs2/glops.c +1
-0@@ -470,14 +470,28 @@ static int inode_go_lock(struct gfs2_holder *gh)static void inode_go_dump (struct seq_file *seq,const struct gfs2_glock *gl) {const struct gfs2_inode *ip = gl->gl_object; +const struct inode *inode;
The inode pointer can be directly initialized to &ip->i_inode even when inode is NULL.
fs/gfs2/glops.c static int inode_go_lock(struct gfs2_holder *gh) · line 475
Quoted 2 lines
fs/gfs2/glops.c +2
-0+const struct address_space *mapping = (const struct address_space *) + (gl +1 );/* Can't use gfs2_glock2aspace due to const */
This introduces code duplication, which seems worse than casting away const here.
fs/gfs2/glops.c static int inode_go_lock(struct gfs2_holder *gh) · line 487
Quoted 13 lines
fs/gfs2/glops.c +10
-1+unsigned long nrpages1, nrpages2; +loff_t i_size; +if (ip ==NULL )return ; - gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu\n", + + inode = &ip->i_inode; +preempt_disable (); + i_size = inode->i_size; + nrpages1 = inode->i_data.nrpages; + nrpages2 = mapping->nrpages; +preempt_enable ();
Please don't open-code i_size_read: it's a simple memory read on the architectures we really care about, and cheap enough on the others.
The nrpages values are protected by xa_lock(&mapping->i_pages). If we really want to make sure we're always reporting correct values on 32-bit architectures, we'd probably have to read nrpages under lock. On 64-bit architectures, I believe we can directly read the nrpages. I agree that nrpages for the data address space can be interesting. Not sure if nrpages for the metadata address space is important enough to bother reporting it though.
fs/gfs2/glops.c static int inode_go_lock(struct gfs2_holder *gh) · line 497
Quoted 12 lines
fs/gfs2/glops.c +3
-1+ +gfs2_print_dbg (seq," I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu p:%lu/%lu\n" , (unsigned long long )ip->i_no_formal_ino, (unsigned long long )ip->i_no_addr,IF2DT (ip->i_inode.i_mode), ip->i_flags, (unsigned int )ip->i_diskflags, - (unsigned long long)i_size_read(&ip->i_inode)); + (unsigned long long )i_size, nrpages1, nrpages2); }/**
Thanks,
Andreas
PATCH v2 1/1 gfs2: Dump nrpages for inodes and their glocks
Hi,
This is my latest version of this patch, revised with Andreas's suggestions:
(1) I got dropped const from the go_dump functions to allow for additional locking without going through hoops.
(2) I got rid of the nrpages for the metadata.
(3) I reverted to previous i_size_read behavior.
(4) I added locking for just the nrpages value.
Regards,
Bob Peterson
Red Hat File Systems
---
This patch is based on an idea from Steve Whitehouse. The idea is to dump the number of pages for inodes in the glock dumps. The additional locking required me to drop const from quite a few places.
--- fs/gfs2/glock.c | 2 +- fs/gfs2/glock.h | 2 +- fs/gfs2/glops.c | 16 ++++++++++++---- fs/gfs2/incore.h | 2 +- fs/gfs2/rgrp.c | 2 +- fs/gfs2/rgrp.h | 2 +- 6 files changed, 17 insertions(+), 9 deletions(-)
fs/gfs2/glock.c +1 -1
@@ -1777,7 +1777,7 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl)* */ -void gfs2_dump_glock (struct seq_file *seq,const struct gfs2_glock *gl) +void gfs2_dump_glock (struct seq_file *seq,struct gfs2_glock *gl) {const struct gfs2_glock_operations *glops = gl->gl_ops;unsigned long long dtime;
fs/gfs2/glock.h +1 -1
@@ -202,7 +202,7 @@ extern int gfs2_glock_nq_num(struct gfs2_sbd *sdp, u64 number, struct gfs2_holder *gh);extern int gfs2_glock_nq_m (unsigned int num_gh,struct gfs2_holder *ghs);extern void gfs2_glock_dq_m (unsigned int num_gh,struct gfs2_holder *ghs); -extern void gfs2_dump_glock (struct seq_file *seq,const struct gfs2_glock *gl); +extern void gfs2_dump_glock (struct seq_file *seq,struct gfs2_glock *gl);#define GLOCK_BUG_ON (gl,x) do { if (unlikely(x)) { gfs2_dump_glock(NULL, gl); BUG(); } } while(0) extern __printf(2, 3) void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...);
fs/gfs2/glops.c +12 -4
@@ -467,17 +467,25 @@ static int inode_go_lock(struct gfs2_holder *gh)* */ -static void inode_go_dump (struct seq_file *seq,const struct gfs2_glock *gl) +static void inode_go_dump (struct seq_file *seq,struct gfs2_glock *gl) { -const struct gfs2_inode *ip = gl->gl_object; +struct gfs2_inode *ip = gl->gl_object; +struct inode *inode = &ip->i_inode; +unsigned long nrpages; +if (ip ==NULL )return ; -gfs2_print_dbg (seq," I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu\n" , + +xa_lock_irq (&inode->i_data.i_pages); + nrpages = inode->i_data.nrpages; +xa_unlock_irq (&inode->i_data.i_pages); + +gfs2_print_dbg (seq," I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu p:%lu\n" , (unsigned long long )ip->i_no_formal_ino, (unsigned long long )ip->i_no_addr,IF2DT (ip->i_inode.i_mode), ip->i_flags, (unsigned int )ip->i_diskflags, - (unsigned long long )i_size_read (&ip->i_inode)); + (unsigned long long )i_size_read (inode), nrpages); }/**
fs/gfs2/incore.h +1 -1
@@ -243,7 +243,7 @@ struct gfs2_glock_operations {int (*go_demote_ok) (const struct gfs2_glock *gl);int (*go_lock) (struct gfs2_holder *gh);void (*go_unlock) (struct gfs2_holder *gh); -void (*go_dump)(struct seq_file *seq,const struct gfs2_glock *gl); +void (*go_dump)(struct seq_file *seq,struct gfs2_glock *gl);void (*go_callback)(struct gfs2_glock *gl,bool remote);const int go_type;const unsigned long go_flags;
fs/gfs2/rgrp.c +1 -1
@@ -2256,7 +2256,7 @@ static void rgblk_free(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd,* */ -void gfs2_rgrp_dump (struct seq_file *seq,const struct gfs2_glock *gl) +void gfs2_rgrp_dump (struct seq_file *seq,struct gfs2_glock *gl) {struct gfs2_rgrpd *rgd = gl->gl_object;struct gfs2_blkreserv *trs;
fs/gfs2/rgrp.h +1 -1
@@ -72,7 +72,7 @@ extern void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist,extern void gfs2_rlist_alloc (struct gfs2_rgrp_list *rlist);extern void gfs2_rlist_free (struct gfs2_rgrp_list *rlist);extern u64 gfs2_ri_total (struct gfs2_sbd *sdp); -extern void gfs2_rgrp_dump (struct seq_file *seq,const struct gfs2_glock *gl); +extern void gfs2_rgrp_dump (struct seq_file *seq,struct gfs2_glock *gl);extern int gfs2_rgrp_send_discards (struct gfs2_sbd *sdp,u64 offset,struct buffer_head *bh,const struct gfs2_bitmap *bi,unsigned minlen,u64 *ptrimmed);
Andreas Gruenbacher
maintainerPATCH v2 1/1 gfs2: Dump nrpages for inodes and their glocks
Quoted 122 lines · Bob Peterson
Hi,
This is my latest version of this patch, revised with Andreas's suggestions:
(1) I got dropped const from thego_dumpfunctions to allow for additional locking without going through hoops.
(2) I got rid of the nrpages for the metadata.
(3) I reverted to previousi_size_readbehavior.
(4) I added locking for just the nrpages value.Regards,
Bob Peterson
Red Hat File Systems
---
This patch is based on an idea from Steve Whitehouse. The idea is to dump the number of pages for inodes in the glock dumps. The additional locking required me to drop const from quite a few places.Signed-off-by Bob Peterson <[email protected]>--- fs/gfs2/glock.c | 2 +- fs/gfs2/glock.h | 2 +- fs/gfs2/glops.c | 16 ++++++++++++---- fs/gfs2/incore.h | 2 +- fs/gfs2/rgrp.c | 2 +- fs/gfs2/rgrp.h | 2 +- 6 files changed, 17 insertions(+), 9 deletions(-)fs/gfs2/glock.c +1
-1@@ -1777,7 +1777,7 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl)* */ -void gfs2_dump_glock (struct seq_file *seq,const struct gfs2_glock *gl) +void gfs2_dump_glock (struct seq_file *seq,struct gfs2_glock *gl) {const struct gfs2_glock_operations *glops = gl->gl_ops;unsigned long long dtime;fs/gfs2/glock.h +1
-1@@ -202,7 +202,7 @@ extern int gfs2_glock_nq_num(struct gfs2_sbd *sdp, u64 number, struct gfs2_holder *gh);extern int gfs2_glock_nq_m (unsigned int num_gh,struct gfs2_holder *ghs);extern void gfs2_glock_dq_m (unsigned int num_gh,struct gfs2_holder *ghs); -extern void gfs2_dump_glock (struct seq_file *seq,const struct gfs2_glock *gl); +extern void gfs2_dump_glock (struct seq_file *seq,struct gfs2_glock *gl);#define GLOCK_BUG_ON (gl,x) do { if (unlikely(x)) { gfs2_dump_glock(NULL, gl); BUG(); } } while(0) extern __printf(2, 3) void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...);fs/gfs2/glops.c +12
-4@@ -467,17 +467,25 @@ static int inode_go_lock(struct gfs2_holder *gh)* */ -static void inode_go_dump (struct seq_file *seq,const struct gfs2_glock *gl) +static void inode_go_dump (struct seq_file *seq,struct gfs2_glock *gl) { -const struct gfs2_inode *ip = gl->gl_object; +struct gfs2_inode *ip = gl->gl_object; +struct inode *inode = &ip->i_inode; +unsigned long nrpages; +if (ip ==NULL )return ; -gfs2_print_dbg (seq," I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu\n" , + +xa_lock_irq (&inode->i_data.i_pages); + nrpages = inode->i_data.nrpages; +xa_unlock_irq (&inode->i_data.i_pages); + +gfs2_print_dbg (seq," I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu p:%lu\n" , (unsigned long long )ip->i_no_formal_ino, (unsigned long long )ip->i_no_addr,IF2DT (ip->i_inode.i_mode), ip->i_flags, (unsigned int )ip->i_diskflags, - (unsigned long long )i_size_read (&ip->i_inode)); + (unsigned long long )i_size_read (inode), nrpages); }/** fs/gfs2/incore.h +1
-1@@ -243,7 +243,7 @@ struct gfs2_glock_operations {int (*go_demote_ok) (const struct gfs2_glock *gl);int (*go_lock) (struct gfs2_holder *gh);void (*go_unlock) (struct gfs2_holder *gh); -void (*go_dump)(struct seq_file *seq,const struct gfs2_glock *gl); +void (*go_dump)(struct seq_file *seq,struct gfs2_glock *gl);void (*go_callback)(struct gfs2_glock *gl,bool remote);const int go_type;const unsigned long go_flags;fs/gfs2/rgrp.c +1
-1@@ -2256,7 +2256,7 @@ static void rgblk_free(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd,* */ -void gfs2_rgrp_dump (struct seq_file *seq,const struct gfs2_glock *gl) +void gfs2_rgrp_dump (struct seq_file *seq,struct gfs2_glock *gl) {struct gfs2_rgrpd *rgd = gl->gl_object;struct gfs2_blkreserv *trs;fs/gfs2/rgrp.h +0
-0
fs/gfs2/rgrp.h extern void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist, · line 78
Quoted 8 lines
fs/gfs2/rgrp.h +1
-1@@ -72,7 +72,7 @@ extern void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist,extern void gfs2_rlist_alloc (struct gfs2_rgrp_list *rlist);extern void gfs2_rlist_free (struct gfs2_rgrp_list *rlist);extern u64 gfs2_ri_total (struct gfs2_sbd *sdp); -extern void gfs2_rgrp_dump (struct seq_file *seq,const struct gfs2_glock *gl); +extern void gfs2_rgrp_dump (struct seq_file *seq,struct gfs2_glock *gl);extern int gfs2_rgrp_send_discards (struct gfs2_sbd *sdp,u64 offset,struct buffer_head *bh,const struct gfs2_bitmap *bi,unsigned minlen,u64 *ptrimmed);
This looks okay as far as I can see.
Thanks,
Andreas