Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1460084 > unrolled thread

Re: [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

Started byDave Chinner <david@fromorbit.com>
First post2016-08-11 01:10 +0200
Last post2016-08-11 02:00 +0200
Articles 20 on this page of 98 — 11 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-11 01:10 +0200
    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression "Huang\, Ying" <ying.huang@intel.com> - 2016-08-11 02:00 +0200
      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression "Huang\, Ying" <ying.huang@intel.com> - 2016-08-11 02:20 +0200
        Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-11 02:30 +0200
          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression "Huang\, Ying" <ying.huang@intel.com> - 2016-08-11 02:40 +0200
            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-11 03:10 +0200
              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-11 06:50 +0200
                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression "Huang\, Ying" <ying.huang@intel.com> - 2016-08-15 19:30 +0200
                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-16 02:30 +0200
              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6%  regression Christoph Hellwig <hch@lst.de> - 2016-08-11 18:00 +0200
                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-11 19:00 +0200
                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression "Huang\, Ying" <ying.huang@intel.com> - 2016-08-11 20:00 +0200
                    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-11 22:00 +0200
                      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6%  regression Christoph Hellwig <hch@lst.de> - 2016-08-11 22:10 +0200
                        Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-11 22:40 +0200
                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Al Viro <viro@ZenIV.linux.org.uk> - 2016-08-12 00:20 +0200
                            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-12 00:40 +0200
                        Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-11 23:50 +0200
                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6%  regression Christoph Hellwig <hch@lst.de> - 2016-08-12 00:10 +0200
                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-12 03:00 +0200
                    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-12 04:30 +0200
                      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-12 06:00 +0200
                        Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-12 20:10 +0200
                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Fengguang Wu <fengguang.wu@intel.com> - 2016-08-14 11:00 +0200
                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-15 02:50 +0200
                            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-15 03:40 +0200
                              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-15 04:40 +0200
                                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-15 05:00 +0200
                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-15 07:10 +0200
                                    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-16 00:30 +0200
                                      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-16 00:50 +0200
                                        Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-16 01:30 +0200
                                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-16 01:50 +0200
                                            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-16 02:50 +0200
                                            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Mel Gorman <mgorman@techsingularity.net> - 2016-08-16 17:10 +0200
                                              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-16 20:00 +0200
                                                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Michal Hocko <mhocko@kernel.org> - 2016-08-17 17:50 +0200
                                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Michal Hocko <mhocko@kernel.org> - 2016-08-17 18:50 +0200
                                                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Mel Gorman <mgorman@techsingularity.net> - 2016-08-17 17:50 +0200
                                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Mel Gorman <mgorman@techsingularity.net> - 2016-08-18 02:50 +0200
                                                    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-18 09:20 +0200
                                                      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Mel Gorman <mgorman@techsingularity.net> - 2016-08-18 15:30 +0200
                                                        Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-19 04:10 +0200
                                                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-19 04:40 +0200
                                                            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Michal Hocko <mhocko@kernel.org> - 2016-08-19 11:10 +0200
                                                            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Mel Gorman <mgorman@techsingularity.net> - 2016-08-19 13:00 +0200
                                                              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-20 01:50 +0200
                                                                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-20 03:10 +0200
                                                                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Mel Gorman <mgorman@techsingularity.net> - 2016-08-20 14:20 +0200
                                                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-19 06:10 +0200
                                                      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Mel Gorman <mgorman@techsingularity.net> - 2016-08-19 17:10 +0200
                                                    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression "Huang\, Ying" <ying.huang@intel.com> - 2016-08-24 17:50 +0200
                                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-18 04:50 +0200
                                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-16 02:20 +0200
                                            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-16 02:40 +0200
                                              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-16 03:00 +0200
                                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-16 02:40 +0200
                                            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-16 04:00 +0200
                                              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-17 00:10 +0200
                                                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-17 01:30 +0200
                                      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-16 01:10 +0200
                                        Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-16 02:40 +0200
                                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-16 02:50 +0200
                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Ingo Molnar <mingo@kernel.org> - 2016-08-15 07:10 +0200
                                    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Peter Zijlstra <peterz@infradead.org> - 2016-08-17 18:30 +0200
                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Fengguang Wu <fengguang.wu@intel.com> - 2016-08-15 15:10 +0200
                    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-12 04:30 +0200
                      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-12 04:40 +0200
                      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6%  regression Christoph Hellwig <hch@lst.de> - 2016-08-12 05:00 +0200
                        Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-12 05:30 +0200
                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-12 06:20 +0200
                            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-12 07:10 +0200
                              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-12 08:10 +0200
                                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Ye Xiaolong <xiaolong.ye@intel.com> - 2016-08-12 08:40 +0200
                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Ye Xiaolong <xiaolong.ye@intel.com> - 2016-08-12 11:00 +0200
                                    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-12 12:10 +0200
                                      Re: [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Fengguang Wu <fengguang.wu@intel.com> - 2016-08-12 12:50 +0200
                                      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6%  regression Christoph Hellwig <hch@lst.de> - 2016-08-13 02:40 +0200
                                        Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6%  regression Christoph Hellwig <hch@lst.de> - 2016-08-14 10:30 +0200
                                          Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Fengguang Wu <fengguang.wu@intel.com> - 2016-08-14 10:40 +0200
                                            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6%  regression Christoph Hellwig <hch@lst.de> - 2016-08-14 11:00 +0200
                                              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Fengguang Wu <fengguang.wu@intel.com> - 2016-08-14 11:30 +0200
                                                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6%  regression Christoph Hellwig <hch@lst.de> - 2016-08-14 18:20 +0200
                                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-15 01:50 +0200
                                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Fengguang Wu <fengguang.wu@intel.com> - 2016-08-15 02:00 +0200
                                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Fengguang Wu <fengguang.wu@intel.com> - 2016-08-15 16:20 +0200
                                                    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-15 23:30 +0200
                                                      Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Fengguang Wu <fengguang.wu@intel.com> - 2016-08-16 14:30 +0200
                                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression "Huang\, Ying" <ying.huang@intel.com> - 2016-08-15 22:40 +0200
                                                    Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6%     regression "Huang\, Ying" <ying.huang@intel.com> - 2016-08-23 00:10 +0200
                                                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Fengguang Wu <fengguang.wu@intel.com> - 2016-08-16 15:30 +0200
                                        Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-14 12:00 +0200
            Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-11 03:20 +0200
              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-11 03:40 +0200
                Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Ye Xiaolong <xiaolong.ye@intel.com> - 2016-08-11 04:50 +0200
                  Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-11 05:20 +0200
              Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Dave Chinner <david@fromorbit.com> - 2016-08-12 03:30 +0200
    Re: [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression Linus Torvalds <torvalds@linux-foundation.org> - 2016-08-11 02:00 +0200

Page 3 of 5 — ← Prev page 1 2 [3] 4 5  Next page →


#1464958 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromDave Chinner <david@fromorbit.com>
Date2016-08-18 09:20 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s7pMl-4SU-13@gated-at.bofh.it>
In reply to#1464861
On Thu, Aug 18, 2016 at 01:45:17AM +0100, Mel Gorman wrote:
> On Wed, Aug 17, 2016 at 04:49:07PM +0100, Mel Gorman wrote:
> > > Yes, we could try to batch the locking like DaveC already suggested
> > > (ie we could move the locking to the caller, and then make
> > > shrink_page_list() just try to keep the lock held for a few pages if
> > > the mapping doesn't change), and that might result in fewer crazy
> > > cacheline ping-pongs overall. But that feels like exactly the wrong
> > > kind of workaround.
> > > 
> > 
> > Even if such batching was implemented, it would be very specific to the
> > case of a single large file filling LRUs on multiple nodes.
> > 
> 
> The latest Jason Bourne movie was sufficiently bad that I spent time
> thinking how the tree_lock could be batched during reclaim. It's not
> straight-forward but this prototype did not blow up on UMA and may be
> worth considering if Dave can test either approach has a positive impact.

SO, I just did a couple of tests. I'll call the two patches "sleepy"
for the contention backoff patch and "bourney" for the Jason Bourne
inspired batching patch. This is an average of 3 runs, overwriting
a 47GB file on a machine with 16GB RAM:

		IO throughput	wall time __pv_queued_spin_lock_slowpath
vanilla		470MB/s		1m42s		25-30%
sleepy		295MB/s		2m43s		<1%
bourney		425MB/s		1m53s		25-30%

The overall CPU usage of sleepy was much lower than the others, but
it was also much slower. Too much sleeping and not enough reclaim
work being done, I think.

As for bourney, it's not immediately clear as to why it's nearly as
bad as the movie. At worst I would have expected it to have not
noticable impact, but maybe we are delaying freeing of pages too
long and so stalling allocation of new pages? It also doesn't do
much to reduce contention, especially considering the reduction in
throughput.

On a hunch that the batch list isn't all one mapping, I sorted it.
Patch is below if you're curious.

		IO throughput	wall time __pv_queued_spin_lock_slowpath
vanilla		470MB/s		1m42s		25-30%
sleepy		295MB/s		2m43s		<1%
bourney		425MB/s		1m53s		25-30%
sorted-bourney	465MB/s		1m43s		20%

The number of reclaim batches (from multiple runs) where the sorting
of the lists would have done anything is counted by list swaps (ls)
being > 1.

# grep " c " /var/log/syslog |grep -v "ls 1" |wc -l
7429
# grep " c " /var/log/syslog |grep "ls 1" |wc -l
1061767

IOWs in 1.07 million batches of pages reclaimed, only ~0.695% of
batches switched to a different mapping tree lock more than once.
From those numbers I would not have expected sorting the page list
to have any measurable impact on performance. However, performance
seems very sensitive to the number of times the mapping tree lock
is bounced around.

FWIW, I just remembered about /proc/sys/vm/zone_reclaim_mode.

		IO throughput	wall time __pv_queued_spin_lock_slowpath
vanilla		470MB/s		1m42s		25-30%
zr=1		470MB/s		1m42s		2-3%

So isolating the page cache usage to a single node maintains
performance and shows a significant reduction in pressure on the
mapping tree lock. Same as a single node system, I'd guess.

Anyway, I've burnt enough erase cycles on this SSD for today....

-Dave.

---
 mm/vmscan.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 9261102..5cf1bd6 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -56,6 +56,8 @@
 
 #include "internal.h"
 
+#include <linux/list_sort.h>
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/vmscan.h>
 
@@ -761,6 +763,17 @@ int remove_mapping(struct address_space *mapping, struct page *page)
 	return ret;
 }
 
+static int mapping_cmp(void *priv, struct list_head *a, struct list_head *b)
+{
+	struct address_space *ma = container_of(a, struct page, lru)->mapping;
+	struct address_space *mb = container_of(a, struct page, lru)->mapping;
+
+	if (ma == mb)
+		return 0;
+	if (ma > mb)
+		return 1;
+	return -1;
+}
 static void remove_mapping_list(struct list_head *mapping_list,
 				struct list_head *free_pages,
 				struct list_head *ret_pages)
@@ -771,12 +784,17 @@ static void remove_mapping_list(struct list_head *mapping_list,
 	LIST_HEAD(swapcache);
 	LIST_HEAD(filecache);
 	struct page *page;
+	int	c = 0, ls = 0;
+
+	list_sort(NULL, mapping_list, mapping_cmp);
 
 	while (!list_empty(mapping_list)) {
+		c++;
 		page = lru_to_page(mapping_list);
 		list_del(&page->lru);
 
 		if (!mapping || page->mapping != mapping) {
+			ls++;
 			if (mapping) {
 				spin_unlock_irqrestore(&mapping->tree_lock, flags);
 				finalise_remove_mapping(&swapcache, &filecache, freepage);
@@ -800,6 +818,7 @@ static void remove_mapping_list(struct list_head *mapping_list,
 		spin_unlock_irqrestore(&mapping->tree_lock, flags);
 		finalise_remove_mapping(&swapcache, &filecache, freepage);
 	}
+	printk("c %d, ls %d\n", c, ls);
 }
 
 /**

> 
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 374d95d04178..926110219cd9 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -621,19 +621,39 @@ static pageout_t pageout(struct page *page, struct address_space *mapping,
>  	return PAGE_CLEAN;
>  }
>  
> +static void finalise_remove_mapping(struct list_head *swapcache,
> +				    struct list_head *filecache,
> +				    void (*freepage)(struct page *))
> +{
> +	struct page *page;
> +
> +	while (!list_empty(swapcache)) {
> +		swp_entry_t swap = { .val = page_private(page) };
> +		page = lru_to_page(swapcache);
> +		list_del(&page->lru);
> +		swapcache_free(swap);
> +		set_page_private(page, 0);
> +	}
> +
> +	while (!list_empty(filecache)) {
> +		page = lru_to_page(swapcache);
> +		list_del(&page->lru);
> +		freepage(page);
> +	}
> +}
> +
>  /*
>   * Same as remove_mapping, but if the page is removed from the mapping, it
>   * gets returned with a refcount of 0.
>   */
> -static int __remove_mapping(struct address_space *mapping, struct page *page,
> -			    bool reclaimed)
> +static int __remove_mapping_page(struct address_space *mapping,
> +				 struct page *page, bool reclaimed,
> +				 struct list_head *swapcache,
> +				 struct list_head *filecache)
>  {
> -	unsigned long flags;
> -
>  	BUG_ON(!PageLocked(page));
>  	BUG_ON(mapping != page_mapping(page));
>  
> -	spin_lock_irqsave(&mapping->tree_lock, flags);
>  	/*
>  	 * The non racy check for a busy page.
>  	 *
> @@ -668,16 +688,18 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
>  	}
>  
>  	if (PageSwapCache(page)) {
> -		swp_entry_t swap = { .val = page_private(page) };
> +		unsigned long swapval = page_private(page);
> +		swp_entry_t swap = { .val = swapval };
>  		mem_cgroup_swapout(page, swap);
>  		__delete_from_swap_cache(page);
> -		spin_unlock_irqrestore(&mapping->tree_lock, flags);
> -		swapcache_free(swap);
> +		set_page_private(page, swapval);
> +		list_add(&page->lru, swapcache);
>  	} else {
> -		void (*freepage)(struct page *);
>  		void *shadow = NULL;
> +		void (*freepage)(struct page *);
>  
>  		freepage = mapping->a_ops->freepage;
> +
>  		/*
>  		 * Remember a shadow entry for reclaimed file cache in
>  		 * order to detect refaults, thus thrashing, later on.
> @@ -698,16 +720,13 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
>  		    !mapping_exiting(mapping) && !dax_mapping(mapping))
>  			shadow = workingset_eviction(mapping, page);
>  		__delete_from_page_cache(page, shadow);
> -		spin_unlock_irqrestore(&mapping->tree_lock, flags);
> -
> -		if (freepage != NULL)
> -			freepage(page);
> +		if (freepage)
> +			list_add(&page->lru, filecache);
>  	}
>  
>  	return 1;
>  
>  cannot_free:
> -	spin_unlock_irqrestore(&mapping->tree_lock, flags);
>  	return 0;
>  }
>  
> @@ -719,16 +738,68 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
>   */
>  int remove_mapping(struct address_space *mapping, struct page *page)
>  {
> -	if (__remove_mapping(mapping, page, false)) {
> +	unsigned long flags;
> +	LIST_HEAD(swapcache);
> +	LIST_HEAD(filecache);
> +	void (*freepage)(struct page *);
> +	int ret = 0;
> +
> +	spin_lock_irqsave(&mapping->tree_lock, flags);
> +	freepage = mapping->a_ops->freepage;
> +
> +	if (__remove_mapping_page(mapping, page, false, &swapcache, &filecache)) {
>  		/*
>  		 * Unfreezing the refcount with 1 rather than 2 effectively
>  		 * drops the pagecache ref for us without requiring another
>  		 * atomic operation.
>  		 */
>  		page_ref_unfreeze(page, 1);
> -		return 1;
> +		ret = 1;
> +	}
> +	spin_unlock_irqrestore(&mapping->tree_lock, flags);
> +	finalise_remove_mapping(&swapcache, &filecache, freepage);
> +	return ret;
> +}
> +
> +static void remove_mapping_list(struct list_head *mapping_list,
> +				struct list_head *free_pages,
> +				struct list_head *ret_pages)
> +{
> +	unsigned long flags;
> +	struct address_space *mapping = NULL;
> +	void (*freepage)(struct page *);
> +	LIST_HEAD(swapcache);
> +	LIST_HEAD(filecache);
> +	struct page *page;
> +
> +	while (!list_empty(mapping_list)) {
> +		page = lru_to_page(mapping_list);
> +		list_del(&page->lru);
> +
> +		if (!mapping || page->mapping != mapping) {
> +			if (mapping) {
> +				spin_unlock_irqrestore(&mapping->tree_lock, flags);
> +				finalise_remove_mapping(&swapcache, &filecache, freepage);
> +			}
> +
> +			mapping = page->mapping;
> +			spin_lock_irqsave(&mapping->tree_lock, flags);
> +			freepage = mapping->a_ops->freepage;
> +		}
> +
> +		if (!__remove_mapping_page(mapping, page, true, &swapcache, &filecache)) {
> +			unlock_page(page);
> +			list_add(&page->lru, ret_pages);
> +		} else {
> +			__ClearPageLocked(page);
> +			list_add(&page->lru, free_pages);
> +		}
> +	}
> +
> +	if (mapping) {
> +		spin_unlock_irqrestore(&mapping->tree_lock, flags);
> +		finalise_remove_mapping(&swapcache, &filecache, freepage);
>  	}
> -	return 0;
>  }
>  
>  /**
> @@ -910,6 +981,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
>  {
>  	LIST_HEAD(ret_pages);
>  	LIST_HEAD(free_pages);
> +	LIST_HEAD(mapping_pages);
>  	int pgactivate = 0;
>  	unsigned long nr_unqueued_dirty = 0;
>  	unsigned long nr_dirty = 0;
> @@ -1206,17 +1278,14 @@ static unsigned long shrink_page_list(struct list_head *page_list,
>  		}
>  
>  lazyfree:
> -		if (!mapping || !__remove_mapping(mapping, page, true))
> +		if (!mapping)
>  			goto keep_locked;
>  
> -		/*
> -		 * At this point, we have no other references and there is
> -		 * no way to pick any more up (removed from LRU, removed
> -		 * from pagecache). Can use non-atomic bitops now (and
> -		 * we obviously don't have to worry about waking up a process
> -		 * waiting on the page lock, because there are no references.
> -		 */
> -		__ClearPageLocked(page);
> +		list_add(&page->lru, &mapping_pages);
> +		if (ret == SWAP_LZFREE)
> +			count_vm_event(PGLAZYFREED);
> +		continue;
> +
>  free_it:
>  		if (ret == SWAP_LZFREE)
>  			count_vm_event(PGLAZYFREED);
> @@ -1251,6 +1320,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
>  		VM_BUG_ON_PAGE(PageLRU(page) || PageUnevictable(page), page);
>  	}
>  
> +	remove_mapping_list(&mapping_pages, &free_pages, &ret_pages);
>  	mem_cgroup_uncharge_list(&free_pages);
>  	try_to_unmap_flush();
>  	free_hot_cold_page_list(&free_pages, true);
> 

-- 
Dave Chinner
david@fromorbit.com

[toc] | [prev] | [next] | [standalone]


#1465334 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromMel Gorman <mgorman@techsingularity.net>
Date2016-08-18 15:30 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s7vyq-kW-59@gated-at.bofh.it>
In reply to#1464958
On Thu, Aug 18, 2016 at 05:11:11PM +1000, Dave Chinner wrote:
> On Thu, Aug 18, 2016 at 01:45:17AM +0100, Mel Gorman wrote:
> > On Wed, Aug 17, 2016 at 04:49:07PM +0100, Mel Gorman wrote:
> > > > Yes, we could try to batch the locking like DaveC already suggested
> > > > (ie we could move the locking to the caller, and then make
> > > > shrink_page_list() just try to keep the lock held for a few pages if
> > > > the mapping doesn't change), and that might result in fewer crazy
> > > > cacheline ping-pongs overall. But that feels like exactly the wrong
> > > > kind of workaround.
> > > > 
> > > 
> > > Even if such batching was implemented, it would be very specific to the
> > > case of a single large file filling LRUs on multiple nodes.
> > > 
> > 
> > The latest Jason Bourne movie was sufficiently bad that I spent time
> > thinking how the tree_lock could be batched during reclaim. It's not
> > straight-forward but this prototype did not blow up on UMA and may be
> > worth considering if Dave can test either approach has a positive impact.
> 
> SO, I just did a couple of tests. I'll call the two patches "sleepy"
> for the contention backoff patch and "bourney" for the Jason Bourne
> inspired batching patch. This is an average of 3 runs, overwriting
> a 47GB file on a machine with 16GB RAM:
> 
> 		IO throughput	wall time __pv_queued_spin_lock_slowpath
> vanilla		470MB/s		1m42s		25-30%
> sleepy		295MB/s		2m43s		<1%
> bourney		425MB/s		1m53s		25-30%
> 

Thanks. I updated the tests today and reran them trying to reproduce what
you saw but I'm simply not seeing it on bare metal with a spinning disk.

xfsio Throughput
                          4.8.0-rc2             4.8.0-rc2             4.8.0-rc2
                            vanilla                sleepy               bourney
Min      tput    147.4450 (  0.00%)    147.2580 (  0.13%)    147.3900 (  0.04%)
Hmean    tput    147.5853 (  0.00%)    147.5101 (  0.05%)    147.6121 ( -0.02%)
Stddev   tput      0.1041 (  0.00%)      0.1785 (-71.47%)      0.2036 (-95.63%)
CoeffVar tput      0.0705 (  0.00%)      0.1210 (-71.56%)      0.1379 (-95.59%)
Max      tput    147.6940 (  0.00%)    147.6420 (  0.04%)    147.8820 ( -0.13%)

I'm currently setting up a KVM instance that may fare better. Due to
quirks of where machines are, I have to setup the KVM instance on real
NUMA hardware but maybe that'll make the problem even more obvious.

> The overall CPU usage of sleepy was much lower than the others, but
> it was also much slower. Too much sleeping and not enough reclaim
> work being done, I think.
> 

Looks like it. On my initial test, there was barely any sleeping.

> As for bourney, it's not immediately clear as to why it's nearly as
> bad as the movie. At worst I would have expected it to have not
> noticable impact, but maybe we are delaying freeing of pages too
> long and so stalling allocation of new pages? It also doesn't do
> much to reduce contention, especially considering the reduction in
> throughput.
> 
> On a hunch that the batch list isn't all one mapping, I sorted it.
> Patch is below if you're curious.
> 

The fact that sorting makes such a difference makes me think that it's
the wrong direction. It's far too specific to this test case and does
nothing to throttle a reclaimer. It's also fairly complex and I expected
that normal users of remove_mapping such as truncation would take a hit.

The hit of bouncing the lock around just hurts too much.

> FWIW, I just remembered about /proc/sys/vm/zone_reclaim_mode.
> 

That is a terrifying "fix" for this problem. It just happens to work
because there is no spillover to other nodes so only one kswapd instance
is potentially active.

> Anyway, I've burnt enough erase cycles on this SSD for today....
> 

I'll continue looking at getting KVM up and running and then consider
other possibilities for throttling.

-- 
Mel Gorman
SUSE Labs

[toc] | [prev] | [next] | [standalone]


#1465886 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2016-08-19 04:10 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s7HpU-7RC-27@gated-at.bofh.it>
In reply to#1465334
On Thu, Aug 18, 2016 at 6:24 AM, Mel Gorman <mgorman@techsingularity.net> wrote:
> On Thu, Aug 18, 2016 at 05:11:11PM +1000, Dave Chinner wrote:
>> FWIW, I just remembered about /proc/sys/vm/zone_reclaim_mode.
>>
>
> That is a terrifying "fix" for this problem. It just happens to work
> because there is no spillover to other nodes so only one kswapd instance
> is potentially active.

Well, it may be a terrifying fix, but it does bring up an intriguing
notion: maybe what we should think about is to make the actual page
cache allocations be more "node-sticky" for a particular mapping? Not
some hard node binding, but if we were to make a single mapping *tend*
to allocate pages primarily within the same node, that would have the
kind of secondary afvantage that it would avoid the cross-node mapping
locking.

Think of it as a gentler "guiding" fix to the spinlock contention
issue than a hard hammer.

And trying to (at least initially) keep the allocations of one
particular file to one particular node sounds like it could have other
locality advantages too.

In fact, looking at the __page_cache_alloc(), we already have that
"spread pages out" logic. I'm assuming Dave doesn't actually have that
bit set (I don't think it's the default), but I'm also envisioning
that maybe we could extend on that notion, and try to spread out
allocations in general, but keep page allocations from one particular
mapping within one node.

The fact that zone_reclaim_mode really improves on Dave's numbers
*that* dramatically does seem to imply that there is something to be
said for this.

We do *not* want to limit the whole page cache to a particular node -
that sounds very unreasonable in general. But limiting any particular
file mapping (by default - I'm sure there are things like databases
that just want their one DB file to take over all of memory) to a
single node sounds much less unreasonable.

What do you guys think? Worth exploring?

                    Linus

[toc] | [prev] | [next] | [standalone]


#1465923 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2016-08-19 04:40 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s7HSW-892-19@gated-at.bofh.it>
In reply to#1465886
On Thu, Aug 18, 2016 at 2:19 PM, Dave Chinner <david@fromorbit.com> wrote:
>
> For streaming or use-once IO it makes a lot of sense to restrict the
> locality of the page cache. The faster the IO device, the less dirty
> page buffering we need to maintain full device bandwidth. And the
> larger the machine the greater the effect of global page cache
> pollution on the other appplications is.

Yes. But I agree with you that it might be very hard to actually get
something that does a good job automagically.

>> In fact, looking at the __page_cache_alloc(), we already have that
>> "spread pages out" logic. I'm assuming Dave doesn't actually have that
>> bit set (I don't think it's the default), but I'm also envisioning
>> that maybe we could extend on that notion, and try to spread out
>> allocations in general, but keep page allocations from one particular
>> mapping within one node.
>
> CONFIG_CPUSETS=y
>
> But I don't have any cpusets configured (unless systemd is doing
> something wacky under the covers) so the page spread bit should not
> be set.

Yeah, but even when it's not set we just do a generic alloc_pages(),
which is just going to fill up all nodes. Not perhaps quite as "spread
out", but there's obviously no attempt to try to be node-aware either.

So _if_ we come up with some reasonable way to say "let's keep the
pages of this mapping together", we could try to do it in that
numa-aware __page_cache_alloc().

It *could* be as simple/stupid as just saying "let's allocate the page
cache for new pages from the current node" - and if the process that
dirties pages just stays around on one single node, that might already
be sufficient.

So just for testing purposes, you could try changing that

        return alloc_pages(gfp, 0);

in __page_cache_alloc() into something like

        return alloc_pages_node(cpu_to_node(raw_smp_processor_id())), gfp, 0);

or something.

>> The fact that zone_reclaim_mode really improves on Dave's numbers
>> *that* dramatically does seem to imply that there is something to be
>> said for this.
>>
>> We do *not* want to limit the whole page cache to a particular node -
>> that sounds very unreasonable in general. But limiting any particular
>> file mapping (by default - I'm sure there are things like databases
>> that just want their one DB file to take over all of memory) to a
>> single node sounds much less unreasonable.
>>
>> What do you guys think? Worth exploring?
>
> The problem is that whenever we turn this sort of behaviour on, some
> benchmark regresses because it no longer holds it's working set in
> the page cache, leading to the change being immediately reverted.
> Enterprise java benchmarks ring a bell, for some reason.

Yeah. It might be ok if we limit the new behavior to just new pages
that get allocated for writing, which is where we want to limit the
page cache more anyway (we already have all those dirty limits etc).

But from a testing standpoint, you can probably try the above
"alloc_pages_node()" hack and see if it even makes a difference. It
might not work, and the dirtier might be moving around too much etc.

             Linus

[toc] | [prev] | [next] | [standalone]


#1466241 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromMichal Hocko <mhocko@kernel.org>
Date2016-08-19 11:10 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s7NYl-3GZ-3@gated-at.bofh.it>
In reply to#1465923
On Thu 18-08-16 15:25:40, Linus Torvalds wrote:
[...]
> So just for testing purposes, you could try changing that
> 
>         return alloc_pages(gfp, 0);
> 
> in __page_cache_alloc() into something like
> 
>         return alloc_pages_node(cpu_to_node(raw_smp_processor_id())), gfp, 0);

That would break mempolicies AFAICS. Anyway, I might be missing
something (the mempolicy kod has a strange sense for aesthetic) but the
normal case without any explicit mempolicy should use default_policy
which is MPOL_PREFERRED and MPOL_F_LOCAL which means numa_node_id() so
the local node. So the above two should do the same thing unless I have
missing something.
-- 
Michal Hocko
SUSE Labs

[toc] | [prev] | [next] | [standalone]


#1466287 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromMel Gorman <mgorman@techsingularity.net>
Date2016-08-19 13:00 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s7PGN-4yC-9@gated-at.bofh.it>
In reply to#1465923
On Thu, Aug 18, 2016 at 03:25:40PM -0700, Linus Torvalds wrote:
> >> In fact, looking at the __page_cache_alloc(), we already have that
> >> "spread pages out" logic. I'm assuming Dave doesn't actually have that
> >> bit set (I don't think it's the default), but I'm also envisioning
> >> that maybe we could extend on that notion, and try to spread out
> >> allocations in general, but keep page allocations from one particular
> >> mapping within one node.
> >
> > CONFIG_CPUSETS=y
> >
> > But I don't have any cpusets configured (unless systemd is doing
> > something wacky under the covers) so the page spread bit should not
> > be set.
> 
> Yeah, but even when it's not set we just do a generic alloc_pages(),
> which is just going to fill up all nodes. Not perhaps quite as "spread
> out", but there's obviously no attempt to try to be node-aware either.
> 

There is a slight difference. Reads should fill the nodes in turn but
dirty pages (__GFP_WRITE) get distributed to balance the number of dirty
pages on each node to avoid hitting dirty balance limits prematurely.

Yesterday I tried a patch that avoids distributing to remote nodes close
to the high watermark to avoid waking remote kswapd instances. It added a
lot of overhead to the fast path (3%) which hurts every writer but did not
reduce contention enough on the special case of writing a single large file.

As an aside, the dirty distribution check itself is very expensive so I
prototyped something that does the expensive calculations on a vmstat
update. Not sure if it'll work but it's a side issue.

> So _if_ we come up with some reasonable way to say "let's keep the
> pages of this mapping together", we could try to do it in that
> numa-aware __page_cache_alloc().
> 
> It *could* be as simple/stupid as just saying "let's allocate the page
> cache for new pages from the current node" - and if the process that
> dirties pages just stays around on one single node, that might already
> be sufficient.
> 
> So just for testing purposes, you could try changing that
> 
>         return alloc_pages(gfp, 0);
> 
> in __page_cache_alloc() into something like
> 
>         return alloc_pages_node(cpu_to_node(raw_smp_processor_id())), gfp, 0);
> 
> or something.
> 

The test would be interesting but I believe that keeping heavy writers
on one node will force them to stall early on dirty balancing even if
there is plenty of free memory on other nodes.

-- 
Mel Gorman
SUSE Labs

[toc] | [prev] | [next] | [standalone]


#1466727 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromDave Chinner <david@fromorbit.com>
Date2016-08-20 01:50 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s81HX-3Le-1@gated-at.bofh.it>
In reply to#1466287
On Fri, Aug 19, 2016 at 11:49:46AM +0100, Mel Gorman wrote:
> On Thu, Aug 18, 2016 at 03:25:40PM -0700, Linus Torvalds wrote:
> > It *could* be as simple/stupid as just saying "let's allocate the page
> > cache for new pages from the current node" - and if the process that
> > dirties pages just stays around on one single node, that might already
> > be sufficient.
> > 
> > So just for testing purposes, you could try changing that
> > 
> >         return alloc_pages(gfp, 0);
> > 
> > in __page_cache_alloc() into something like
> > 
> >         return alloc_pages_node(cpu_to_node(raw_smp_processor_id())), gfp, 0);
> > 
> > or something.
> > 
> 
> The test would be interesting but I believe that keeping heavy writers
> on one node will force them to stall early on dirty balancing even if
> there is plenty of free memory on other nodes.

Well, it depends on the speed of the storage. The higher the speed
of the storage, the less we care about stalling on dirty pages
during reclaim. i.e. faster storage == shorter stalls. We really
should stop thinking we need to optimise reclaim purely for the
benefit of slow disks.  500MB/s write speed with latencies of a
under a couple of milliseconds is common hardware these days. pcie
based storage (e.g. m2, nvme) is rapidly becoming commonplace and
they can easily do 1-2GB/s write speeds.

The fast storage devices that are arriving need to be treated
more like a fast network device (e.g. a pci-e 4x nvme SSD has the
throughput of 2x10GbE devices). We have to consider if buffering
streaming data in the page cache for any longer than it takes to get
the data to userspace or to disk is worth the cost of reclaiming it
from the page cache.

Really, the question that needs to be answered is this: if we can
pull data from the storage at similar speeds and latencies as we can
from the page cache, then *why are we caching that data*?

We've already made that "don't cache for fast storage" decision in
the case of pmem - the DAX IO path is slowly moving towards making
full use of the mapping infrastructure for all it's tracking
requirements. pcie based storage is a bit slower than pmem, but
the principle is the same - the storage is sufficiently fast that
caching only really makes sense for data that is really hot...

I think the underlying principle here is that the faster the backing
device, the less we should cache and buffer the device in the OS. I
suspect a good initial approximation of "stickiness" for the page
cache would the speed of writeback as measured by the BDI underlying
the mapping....

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

[toc] | [prev] | [next] | [standalone]


#1466762 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2016-08-20 03:10 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s82Xo-4H4-5@gated-at.bofh.it>
In reply to#1466727
On Fri, Aug 19, 2016 at 4:48 PM, Dave Chinner <david@fromorbit.com> wrote:
>
> Well, it depends on the speed of the storage. The higher the speed
> of the storage, the less we care about stalling on dirty pages
> during reclaim

Actually, that's largely true independently of the speed of the storage, I feel.

On really fast storage, you might as well push it out and buffering
lots of dirty memory pointless. And on really slow storage, buffering
lots of dirty memory is absolutely *horrible* from a latency
standpoint.

So I don't think this is about fast-vs-slow disks.

I think a lot of our "let's aggressively buffer dirty data" is
entirely historical. When you had 16MB of RAM in a workstation,
aggressively using half of it for writeback caches meant that you
could do things like untar source trees without waiting for IO.

But when you have 16GB of RAM in a workstation, and terabytes of RAM
in multi-node big machines, it's kind of silly to talk about
"percentages of memory available" for dirty data. I think it's likely
silly to even see "one node worth of memory" as being some limiter.

So I think we should try to avoid stalling on dirty pages during
reclaim by simply aiming to have fewer dirty pages in the first place.
Not because the stall is shorter on a fast disk, but because we just
shouldn't use that much memory for dirty data.

                 Linus

[toc] | [prev] | [next] | [standalone]


#1466813 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromMel Gorman <mgorman@techsingularity.net>
Date2016-08-20 14:20 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s8dpL-2O3-7@gated-at.bofh.it>
In reply to#1466727
On Sat, Aug 20, 2016 at 09:48:39AM +1000, Dave Chinner wrote:
> On Fri, Aug 19, 2016 at 11:49:46AM +0100, Mel Gorman wrote:
> > On Thu, Aug 18, 2016 at 03:25:40PM -0700, Linus Torvalds wrote:
> > > It *could* be as simple/stupid as just saying "let's allocate the page
> > > cache for new pages from the current node" - and if the process that
> > > dirties pages just stays around on one single node, that might already
> > > be sufficient.
> > > 
> > > So just for testing purposes, you could try changing that
> > > 
> > >         return alloc_pages(gfp, 0);
> > > 
> > > in __page_cache_alloc() into something like
> > > 
> > >         return alloc_pages_node(cpu_to_node(raw_smp_processor_id())), gfp, 0);
> > > 
> > > or something.
> > > 
> > 
> > The test would be interesting but I believe that keeping heavy writers
> > on one node will force them to stall early on dirty balancing even if
> > there is plenty of free memory on other nodes.
> 
> Well, it depends on the speed of the storage. The higher the speed
> of the storage, the less we care about stalling on dirty pages
> during reclaim. i.e. faster storage == shorter stalls. We really
> should stop thinking we need to optimise reclaim purely for the
> benefit of slow disks.  500MB/s write speed with latencies of a
> under a couple of milliseconds is common hardware these days. pcie
> based storage (e.g. m2, nvme) is rapidly becoming commonplace and
> they can easily do 1-2GB/s write speeds.
> 

I partially agree. I've been of the opinion for a long time that dirty_time
would be desirable and limit the amount of dirty data by microseconds
required to sync the data and pick a default like 5 seconds. It's
non-trivial as the write speed of all BDIs would have to be estimated
and on rotary storage the estimate would be unreliable.

A short-term practical idea would be to distribute pages for writing
only when the dirty limit is almost reached on a given node. For fast
storage, the distribution may never happen.

Neither idea would actually impact the current problem though unless it
was combined with discarding clean cache agressively if the underlying
storage is fast. Hence, it would still be nice if the contention problem
could be mitigated. Did that last patch help any?

-- 
Mel Gorman
SUSE Labs

[toc] | [prev] | [next] | [standalone]


#1465973 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromDave Chinner <david@fromorbit.com>
Date2016-08-19 06:10 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s7HSW-892-21@gated-at.bofh.it>
In reply to#1465886
On Thu, Aug 18, 2016 at 10:55:01AM -0700, Linus Torvalds wrote:
> On Thu, Aug 18, 2016 at 6:24 AM, Mel Gorman <mgorman@techsingularity.net> wrote:
> > On Thu, Aug 18, 2016 at 05:11:11PM +1000, Dave Chinner wrote:
> >> FWIW, I just remembered about /proc/sys/vm/zone_reclaim_mode.
> >>
> >
> > That is a terrifying "fix" for this problem. It just happens to work
> > because there is no spillover to other nodes so only one kswapd instance
> > is potentially active.
> 
> Well, it may be a terrifying fix, but it does bring up an intriguing
> notion: maybe what we should think about is to make the actual page
> cache allocations be more "node-sticky" for a particular mapping? Not
> some hard node binding, but if we were to make a single mapping *tend*
> to allocate pages primarily within the same node, that would have the
> kind of secondary afvantage that it would avoid the cross-node mapping
> locking.

For streaming or use-once IO it makes a lot of sense to restrict the
locality of the page cache. The faster the IO device, the less dirty
page buffering we need to maintain full device bandwidth. And the
larger the machine the greater the effect of global page cache
pollution on the other appplications is.

> Think of it as a gentler "guiding" fix to the spinlock contention
> issue than a hard hammer.
> 
> And trying to (at least initially) keep the allocations of one
> particular file to one particular node sounds like it could have other
> locality advantages too.
> 
> In fact, looking at the __page_cache_alloc(), we already have that
> "spread pages out" logic. I'm assuming Dave doesn't actually have that
> bit set (I don't think it's the default), but I'm also envisioning
> that maybe we could extend on that notion, and try to spread out
> allocations in general, but keep page allocations from one particular
> mapping within one node.

CONFIG_CPUSETS=y

But I don't have any cpusets configured (unless systemd is doing
something wacky under the covers) so the page spread bit should not
be set.

> The fact that zone_reclaim_mode really improves on Dave's numbers
> *that* dramatically does seem to imply that there is something to be
> said for this.
> 
> We do *not* want to limit the whole page cache to a particular node -
> that sounds very unreasonable in general. But limiting any particular
> file mapping (by default - I'm sure there are things like databases
> that just want their one DB file to take over all of memory) to a
> single node sounds much less unreasonable.
> 
> What do you guys think? Worth exploring?

The problem is that whenever we turn this sort of behaviour on, some
benchmark regresses because it no longer holds it's working set in
the page cache, leading to the change being immediately reverted.
Enterprise java benchmarks ring a bell, for some reason.

Hence my comment above about needing it to be tied into specific
"use-once-only" page cache behaviours. I know we have working set
estimation, fadvise modes and things like readahead that help track
sequential and use-once access patterns, but I'm not sure how we can
tie that all together....

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

[toc] | [prev] | [next] | [standalone]


#1466481 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromMel Gorman <mgorman@techsingularity.net>
Date2016-08-19 17:10 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s7TAJ-7du-11@gated-at.bofh.it>
In reply to#1464958
On Thu, Aug 18, 2016 at 05:11:11PM +1000, Dave Chinner wrote:
> On Thu, Aug 18, 2016 at 01:45:17AM +0100, Mel Gorman wrote:
> > On Wed, Aug 17, 2016 at 04:49:07PM +0100, Mel Gorman wrote:
> > > > Yes, we could try to batch the locking like DaveC already suggested
> > > > (ie we could move the locking to the caller, and then make
> > > > shrink_page_list() just try to keep the lock held for a few pages if
> > > > the mapping doesn't change), and that might result in fewer crazy
> > > > cacheline ping-pongs overall. But that feels like exactly the wrong
> > > > kind of workaround.
> > > > 
> > > 
> > > Even if such batching was implemented, it would be very specific to the
> > > case of a single large file filling LRUs on multiple nodes.
> > > 
> > 
> > The latest Jason Bourne movie was sufficiently bad that I spent time
> > thinking how the tree_lock could be batched during reclaim. It's not
> > straight-forward but this prototype did not blow up on UMA and may be
> > worth considering if Dave can test either approach has a positive impact.
> 
> SO, I just did a couple of tests. I'll call the two patches "sleepy"
> for the contention backoff patch and "bourney" for the Jason Bourne
> inspired batching patch. This is an average of 3 runs, overwriting
> a 47GB file on a machine with 16GB RAM:
> 
> 		IO throughput	wall time __pv_queued_spin_lock_slowpath
> vanilla		470MB/s		1m42s		25-30%
> sleepy		295MB/s		2m43s		<1%
> bourney		425MB/s		1m53s		25-30%
> 

This is another blunt-force patch that

a) stalls all but one kswapd instance when treelock contention occurs
b) marks a pgdat congested when tree_lock contention is encountered
   which may cause direct reclaimers to wait_iff_congested until
   kswapd finishes balancing the node

I tested this on a KVM instance running on a 4-socket box. The vCPUs
were bound to pCPUs and the memory nodes in the KVM mapped to physical
memory nodes. Without the patch 3% of kswapd cycles were spent on
locking. With the patch, the cycle count was 0.23%

xfs_io contention was reduced from 0.63% to 0.39% which is not perfect.
It can be reduced by stalling all kswapd instances but then xfs_io direct
reclaims and throughput drops.

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index d572b78b65e1..f6d3e886f405 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -532,6 +532,7 @@ enum pgdat_flags {
 					 * many pages under writeback
 					 */
 	PGDAT_RECLAIM_LOCKED,		/* prevents concurrent reclaim */
+	PGDAT_CONTENDED,		/* kswapd contending on tree_lock */
 };
 
 static inline unsigned long zone_end_pfn(const struct zone *zone)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 374d95d04178..64ca2148755c 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -621,19 +621,43 @@ static pageout_t pageout(struct page *page, struct address_space *mapping,
 	return PAGE_CLEAN;
 }
 
+static atomic_t kswapd_contended = ATOMIC_INIT(0);
+
 /*
  * Same as remove_mapping, but if the page is removed from the mapping, it
  * gets returned with a refcount of 0.
  */
 static int __remove_mapping(struct address_space *mapping, struct page *page,
-			    bool reclaimed)
+			    bool reclaimed, unsigned long *nr_contended)
 {
 	unsigned long flags;
 
 	BUG_ON(!PageLocked(page));
 	BUG_ON(mapping != page_mapping(page));
 
-	spin_lock_irqsave(&mapping->tree_lock, flags);
+	if (!nr_contended || !current_is_kswapd())
+		spin_lock_irqsave(&mapping->tree_lock, flags);
+	else {
+		/* Account for trylock contentions in kswapd */
+		if (!spin_trylock_irqsave(&mapping->tree_lock, flags)) {
+			pg_data_t *pgdat = page_pgdat(page);
+			int nr_kswapd;
+
+			/* Account for contended pages and contended kswapds */
+			(*nr_contended)++;
+			if (!test_and_set_bit(PGDAT_CONTENDED, &pgdat->flags))
+				nr_kswapd = atomic_inc_return(&kswapd_contended);
+			else
+				nr_kswapd = atomic_read(&kswapd_contended);
+			BUG_ON(nr_kswapd > nr_online_nodes || nr_kswapd < 0);
+
+			/* Stall kswapd if multiple kswapds are contending */
+			if (nr_kswapd > 1)
+				congestion_wait(BLK_RW_ASYNC, HZ/10);
+
+			spin_lock_irqsave(&mapping->tree_lock, flags);
+		}
+	}
 	/*
 	 * The non racy check for a busy page.
 	 *
@@ -719,7 +743,7 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
  */
 int remove_mapping(struct address_space *mapping, struct page *page)
 {
-	if (__remove_mapping(mapping, page, false)) {
+	if (__remove_mapping(mapping, page, false, NULL)) {
 		/*
 		 * Unfreezing the refcount with 1 rather than 2 effectively
 		 * drops the pagecache ref for us without requiring another
@@ -906,6 +930,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
 				      unsigned long *ret_nr_congested,
 				      unsigned long *ret_nr_writeback,
 				      unsigned long *ret_nr_immediate,
+				      unsigned long *ret_nr_contended,
 				      bool force_reclaim)
 {
 	LIST_HEAD(ret_pages);
@@ -917,6 +942,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
 	unsigned long nr_reclaimed = 0;
 	unsigned long nr_writeback = 0;
 	unsigned long nr_immediate = 0;
+	unsigned long nr_contended = 0;
 
 	cond_resched();
 
@@ -1206,7 +1232,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
 		}
 
 lazyfree:
-		if (!mapping || !__remove_mapping(mapping, page, true))
+		if (!mapping || !__remove_mapping(mapping, page, true, &nr_contended))
 			goto keep_locked;
 
 		/*
@@ -1263,6 +1289,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
 	*ret_nr_unqueued_dirty += nr_unqueued_dirty;
 	*ret_nr_writeback += nr_writeback;
 	*ret_nr_immediate += nr_immediate;
+	*ret_nr_contended += nr_contended;
 	return nr_reclaimed;
 }
 
@@ -1274,7 +1301,7 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone,
 		.priority = DEF_PRIORITY,
 		.may_unmap = 1,
 	};
-	unsigned long ret, dummy1, dummy2, dummy3, dummy4, dummy5;
+	unsigned long ret, dummy1, dummy2, dummy3, dummy4, dummy5, dummy6;
 	struct page *page, *next;
 	LIST_HEAD(clean_pages);
 
@@ -1288,7 +1315,7 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone,
 
 	ret = shrink_page_list(&clean_pages, zone->zone_pgdat, &sc,
 			TTU_UNMAP|TTU_IGNORE_ACCESS,
-			&dummy1, &dummy2, &dummy3, &dummy4, &dummy5, true);
+			&dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, true);
 	list_splice(&clean_pages, page_list);
 	mod_node_page_state(zone->zone_pgdat, NR_ISOLATED_FILE, -ret);
 	return ret;
@@ -1693,6 +1720,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
 	unsigned long nr_unqueued_dirty = 0;
 	unsigned long nr_writeback = 0;
 	unsigned long nr_immediate = 0;
+	unsigned long nr_contended = 0;
 	isolate_mode_t isolate_mode = 0;
 	int file = is_file_lru(lru);
 	struct pglist_data *pgdat = lruvec_pgdat(lruvec);
@@ -1738,7 +1766,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
 
 	nr_reclaimed = shrink_page_list(&page_list, pgdat, sc, TTU_UNMAP,
 				&nr_dirty, &nr_unqueued_dirty, &nr_congested,
-				&nr_writeback, &nr_immediate,
+				&nr_writeback, &nr_immediate, &nr_contended,
 				false);
 
 	spin_lock_irq(&pgdat->lru_lock);
@@ -1789,6 +1817,15 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
 			set_bit(PGDAT_CONGESTED, &pgdat->flags);
 
 		/*
+		 * Tag a zone as congested if kswapd encounters contended pages
+		 * as it may indicate contention with a heavy writer or
+		 * other kswapd instances. The tag may stall direct reclaimers
+		 * in wait_iff_congested.
+		 */
+		if (nr_contended && current_is_kswapd())
+			set_bit(PGDAT_CONGESTED, &pgdat->flags);
+
+		/*
 		 * If dirty pages are scanned that are not queued for IO, it
 		 * implies that flushers are not keeping up. In this case, flag
 		 * the pgdat PGDAT_DIRTY and kswapd will start writing pages from
@@ -1805,6 +1842,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
 		 */
 		if (nr_immediate && current_may_throttle())
 			congestion_wait(BLK_RW_ASYNC, HZ/10);
+
 	}
 
 	/*
@@ -3109,6 +3147,9 @@ static bool zone_balanced(struct zone *zone, int order, int classzone_idx)
 	clear_bit(PGDAT_CONGESTED, &zone->zone_pgdat->flags);
 	clear_bit(PGDAT_DIRTY, &zone->zone_pgdat->flags);
 
+	if (test_and_clear_bit(PGDAT_CONTENDED, &zone->zone_pgdat->flags))
+		atomic_dec(&kswapd_contended);
+
 	return true;
 }
 

[toc] | [prev] | [next] | [standalone]


#1469552 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

From"Huang\, Ying" <ying.huang@intel.com>
Date2016-08-24 17:50 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s9IBb-4fO-11@gated-at.bofh.it>
In reply to#1464861
Hi, Mel,

Mel Gorman <mgorman@techsingularity.net> writes:

> On Wed, Aug 17, 2016 at 04:49:07PM +0100, Mel Gorman wrote:
>> > Yes, we could try to batch the locking like DaveC already suggested
>> > (ie we could move the locking to the caller, and then make
>> > shrink_page_list() just try to keep the lock held for a few pages if
>> > the mapping doesn't change), and that might result in fewer crazy
>> > cacheline ping-pongs overall. But that feels like exactly the wrong
>> > kind of workaround.
>> > 
>> 
>> Even if such batching was implemented, it would be very specific to the
>> case of a single large file filling LRUs on multiple nodes.
>> 
>
> The latest Jason Bourne movie was sufficiently bad that I spent time
> thinking how the tree_lock could be batched during reclaim. It's not
> straight-forward but this prototype did not blow up on UMA and may be
> worth considering if Dave can test either approach has a positive impact.
>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 374d95d04178..926110219cd9 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -621,19 +621,39 @@ static pageout_t pageout(struct page *page, struct address_space *mapping,
>  	return PAGE_CLEAN;
>  }

We found this patch helps much for swap out performance, where there are
usually only one mapping for all swap pages.  In our 16 processes
sequential swap write test case for a ramdisk on a Xeon E5 v3 machine,
the swap out throughput improved 40.4%, from ~0.97GB/s to ~1.36GB/s.
What's your plan for this patch?  If it can be merged soon, that will be
great!

I found some issues in the original patch to work with swap cache.  Below
is my fixes to make it work for swap cache.

Best Regards,
Huang, Ying

-------------------------------------------------------------------->

diff --git a/mm/vmscan.c b/mm/vmscan.c
index ac5fbff..dcaf295 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -623,22 +623,28 @@ static pageout_t pageout(struct page *page, struct address_space *mapping,
 
 static void finalise_remove_mapping(struct list_head *swapcache,
 				    struct list_head *filecache,
+				    struct list_head *free_pages,
 				    void (*freepage)(struct page *))
 {
 	struct page *page;
 
 	while (!list_empty(swapcache)) {
-		swp_entry_t swap = { .val = page_private(page) };
+		swp_entry_t swap;
 		page = lru_to_page(swapcache);
 		list_del(&page->lru);
+		swap.val = page_private(page);
 		swapcache_free(swap);
 		set_page_private(page, 0);
+		if (free_pages)
+			list_add(&page->lru, free_pages);
 	}
 
 	while (!list_empty(filecache)) {
-		page = lru_to_page(swapcache);
+		page = lru_to_page(filecache);
 		list_del(&page->lru);
 		freepage(page);
+		if (free_pages)
+			list_add(&page->lru, free_pages);
 	}
 }
 
@@ -649,7 +655,8 @@ static void finalise_remove_mapping(struct list_head *swapcache,
 static int __remove_mapping_page(struct address_space *mapping,
 				 struct page *page, bool reclaimed,
 				 struct list_head *swapcache,
-				 struct list_head *filecache)
+				 struct list_head *filecache,
+				 struct list_head *free_pages)
 {
 	BUG_ON(!PageLocked(page));
 	BUG_ON(mapping != page_mapping(page));
@@ -722,6 +729,8 @@ static int __remove_mapping_page(struct address_space *mapping,
 		__delete_from_page_cache(page, shadow);
 		if (freepage)
 			list_add(&page->lru, filecache);
+		else if (free_pages)
+			list_add(&page->lru, free_pages);
 	}
 
 	return 1;
@@ -747,7 +756,7 @@ int remove_mapping(struct address_space *mapping, struct page *page)
 	spin_lock_irqsave(&mapping->tree_lock, flags);
 	freepage = mapping->a_ops->freepage;
 
-	if (__remove_mapping_page(mapping, page, false, &swapcache, &filecache)) {
+	if (__remove_mapping_page(mapping, page, false, &swapcache, &filecache, NULL)) {
 		/*
 		 * Unfreezing the refcount with 1 rather than 2 effectively
 		 * drops the pagecache ref for us without requiring another
@@ -757,7 +766,7 @@ int remove_mapping(struct address_space *mapping, struct page *page)
 		ret = 1;
 	}
 	spin_unlock_irqrestore(&mapping->tree_lock, flags);
-	finalise_remove_mapping(&swapcache, &filecache, freepage);
+	finalise_remove_mapping(&swapcache, &filecache, NULL, freepage);
 	return ret;
 }
 
@@ -776,29 +785,28 @@ static void remove_mapping_list(struct list_head *mapping_list,
 		page = lru_to_page(mapping_list);
 		list_del(&page->lru);
 
-		if (!mapping || page->mapping != mapping) {
+		if (!mapping || page_mapping(page) != mapping) {
 			if (mapping) {
 				spin_unlock_irqrestore(&mapping->tree_lock, flags);
-				finalise_remove_mapping(&swapcache, &filecache, freepage);
+				finalise_remove_mapping(&swapcache, &filecache, free_pages, freepage);
 			}
 
-			mapping = page->mapping;
+			mapping = page_mapping(page);
 			spin_lock_irqsave(&mapping->tree_lock, flags);
 			freepage = mapping->a_ops->freepage;
 		}
 
-		if (!__remove_mapping_page(mapping, page, true, &swapcache, &filecache)) {
+		if (!__remove_mapping_page(mapping, page, true, &swapcache,
+					   &filecache, free_pages)) {
 			unlock_page(page);
 			list_add(&page->lru, ret_pages);
-		} else {
+		} else
 			__ClearPageLocked(page);
-			list_add(&page->lru, free_pages);
-		}
 	}
 
 	if (mapping) {
 		spin_unlock_irqrestore(&mapping->tree_lock, flags);
-		finalise_remove_mapping(&swapcache, &filecache, freepage);
+		finalise_remove_mapping(&swapcache, &filecache, free_pages, freepage);
 	}
 }
 

[toc] | [prev] | [next] | [standalone]


#1464902 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromDave Chinner <david@fromorbit.com>
Date2016-08-18 04:50 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s7lz4-1Pc-1@gated-at.bofh.it>
In reply to#1464631
On Wed, Aug 17, 2016 at 04:49:07PM +0100, Mel Gorman wrote:
> On Tue, Aug 16, 2016 at 10:47:36AM -0700, Linus Torvalds wrote:
> > I've always preferred to see direct reclaim as the primary model for
> > reclaim, partly in order to throttle the actual "bad" process, but
> > also because "kswapd uses lots of CPU time" is such a nasty thing to
> > even begin guessing about.
> > 
> 
> While I agree that bugs with high CPU usage from kswapd are a pain,
> I'm reluctant to move towards direct reclaim being the primary mode. The
> stalls can be severe and there is no guarantee that the process punished
> is the process responsible. I'm basing this assumption on observations
> of severe performance regressions when I accidentally broke kswapd during
> the development of node-lru.
> 
> > So I have to admit to liking that "make kswapd sleep a bit if it's
> > just looping" logic that got removed in that commit.
> > 
> 
> It's primarily the direct reclaimer that is affected by that patch.
> 
> > And looking at DaveC's numbers, it really feels like it's not even
> > what we do inside the locked region that is the problem. Sure,
> > __delete_from_page_cache() (which is most of it) is at 1.86% of CPU
> > time (when including all the things it calls), but that still isn't
> > all that much. Especially when compared to just:
> > 
> >    0.78%  [kernel]  [k] _raw_spin_unlock_irqrestore
> > 
> 
> The profile is shocking for such a basic workload. I automated what Dave
> described with xfs_io except that the file size is 2*RAM. The filesystem
> is sized to be roughly the same size as the file to minimise variances
> due to block layout. A call-graph profile collected on bare metal UMA with
> numa=fake=4 and paravirt spinlocks showed
> 
>      1.40%     0.16%  kswapd1          [kernel.vmlinux]            [k] _raw_spin_lock_irqsave
>      1.36%     0.16%  kswapd2          [kernel.vmlinux]            [k] _raw_spin_lock_irqsave
>      1.21%     0.12%  kswapd0          [kernel.vmlinux]            [k] _raw_spin_lock_irqsave
>      1.12%     0.13%  kswapd3          [kernel.vmlinux]            [k] _raw_spin_lock_irqsave
>      0.81%     0.45%  xfs_io           [kernel.vmlinux]            [k] _raw_spin_lock_irqsave
> 
> Those contention figures are not great but they are not terrible either. The
> vmstats told me there was no direct reclaim activity so either my theory
> is wrong or this machine is not reproducing the same problem Dave is seeing.

No, that's roughly the same un-normalised CPU percentage I am seeing
in spinlock contention. i.e. take way the idle CPU in the profile
(probably upwards of 80% if it's a 16p machine), and instead look at
that figure as a percentage of total CPU used by the workload. Then
you'll that it's 30-40% of the total CPU consumed by the workload.

> I have partial results from a 2-socket and 4-socket machine. 2-socket spends
> roughtly 1.8% in _raw_spin_lock_irqsave and 4-socket spends roughtly 3%,
> both with no direct reclaim. Clearly the problem gets worse the more NUMA
> nodes there are but not to the same extent Dave reports.
> 
> I believe potential reasons why I do not see the same problem as Dave are;
> 
> 1. Different memory sizes changing timing
> 2. Dave has fast storage and I'm using a spinning disk

This particular is using an abused 3 year old SATA SSD that still
runs at 500MB/s on sequential writes. This is "cheap desktop"
capability these days and is nowhere near what I'd call "fast".

> 3. Lock contention problems are magnified inside KVM
> 
> I think 3 is a good possibility if contended locks result in expensive
> exiting and reentery of the guest. I have a vague recollection that a
> spinning vcpu exits the guest but I did not confirm that.

I don't think anything like that has been implemented in the pv
spinlocks yet. They just spin right now - it's the same lock
implementation as the host. Also, Context switch rates measured on
the host are not significantly higher than what is measured in the
guest, so there doesn't appear to be any extra scheduling on the
host side occurring.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

[toc] | [prev] | [next] | [standalone]


#1463294 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2016-08-16 02:20 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s6AgO-4eu-25@gated-at.bofh.it>
In reply to#1463272
On Mon, Aug 15, 2016 at 4:20 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> But I'll try to see what happens
> on my profile, even if I can't recreate the contention itself, just
> trying to see what happens inside of that region.

Yeah, since I run my machines on encrypted disks, my profile shows 60%
kthread, but that's just because 55% is crypto.

I only have 5% in kswapd. And the spinlock doesn't even show up for me
(but "__delete_from_page_cache()" does, which doesn't look
unreasonable).

And while the biggest reason the spinlock doesn't show up is likely
simply my single-node "everything is on one die", I still think the
lower kswapd CPU use might be partly due to the node-vs-zone thing.

For me, with just one node, the new

            test_bit(PGDAT_WRITEBACK, &pgdat->flags)) {

ends up being very similar to what we used to have before, ie

            test_bit(ZONE_WRITEBACK, &zone->flags)) {

but on a multi-node machine it would be rather different.

So I might never see contention anyway.

The basic logic in shrink_swap_list() goes back to commit 283aba9f9e0
("mm: vmscan: block kswapd if it is encountering pages under
writeback") but it has been messed around with a lot (and something
else existed there before - we've always had some "throttle kswapd so
that it doesn't use insane amounts of CPU time").

DaveC - does the spinlock contention go away if you just go back to
4.7? If so, I think it's the new zone thing. But it would be good to
verify - maybe it's something entirely different and it goes back much
further.

Mel - I may be barking up entirely the wrong tree, but it would be
good if you could take a look just in case this is actually it.

                  Linus

[toc] | [prev] | [next] | [standalone]


#1463308 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromDave Chinner <david@fromorbit.com>
Date2016-08-16 02:40 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s6AAa-4mv-9@gated-at.bofh.it>
In reply to#1463294
On Mon, Aug 15, 2016 at 05:15:47PM -0700, Linus Torvalds wrote:
> DaveC - does the spinlock contention go away if you just go back to
> 4.7? If so, I think it's the new zone thing. But it would be good to
> verify - maybe it's something entirely different and it goes back much
> further.

Same in 4.7 (flat profile numbers climbed higher after this
snapshot was taken, as can be seen by the callgraph numbers):

  29.47%  [kernel]  [k] __pv_queued_spin_lock_slowpath
  11.59%  [kernel]  [k] copy_user_generic_string
   3.13%  [kernel]  [k] __raw_callee_save___pv_queued_spin_unlock
   2.87%  [kernel]  [k] __block_commit_write.isra.29
   2.02%  [kernel]  [k] _raw_spin_lock_irqsave
   1.77%  [kernel]  [k] get_page_from_freelist
   1.36%  [kernel]  [k] __wake_up_bit     
   1.31%  [kernel]  [k] __radix_tree_lookup
   1.22%  [kernel]  [k] radix_tree_tag_set
   1.16%  [kernel]  [k] clear_page_dirty_for_io
   1.14%  [kernel]  [k] __remove_mapping
   1.14%  [kernel]  [k] _raw_spin_lock
   1.00%  [kernel]  [k] zone_dirty_ok
   0.95%  [kernel]  [k] radix_tree_tag_clear
   0.90%  [kernel]  [k] generic_write_end
   0.89%  [kernel]  [k] __delete_from_page_cache
   0.87%  [kernel]  [k] unlock_page
   0.86%  [kernel]  [k] cancel_dirty_page
   0.81%  [kernel]  [k] up_write
   0.80%  [kernel]  [k] ___might_sleep
   0.77%  [kernel]  [k] _raw_spin_unlock_irqrestore
   0.75%  [kernel]  [k] generic_perform_write
   0.72%  [kernel]  [k] xfs_do_writepage  
   0.69%  [kernel]  [k] down_write        
   0.63%  [kernel]  [k] shrink_page_list  
   0.63%  [kernel]  [k] __xfs_get_blocks  
   0.61%  [kernel]  [k] __test_set_page_writeback
   0.59%  [kernel]  [k] free_hot_cold_page
   0.57%  [kernel]  [k] write_cache_pages
   0.56%  [kernel]  [k] __radix_tree_create
   0.55%  [kernel]  [k] __list_add
   0.53%  [kernel]  [k] page_mapping
   0.53%  [kernel]  [k] drop_buffers
   0.51%  [kernel]  [k] xfs_vm_releasepage
   0.51%  [kernel]  [k] free_pcppages_bulk
   0.50%  [kernel]  [k] __list_del_entry  


   38.07%    38.07%  [kernel]            [k] __pv_queued_spin_lock_slowpath
   - 25.52% ret_from_fork
      - kthread
         - 24.36% kswapd
              shrink_zone
              shrink_zone_memcg.isra.73
              shrink_inactive_list
         - 3.21% worker_thread
              process_one_work
              wb_workfn
              wb_writeback
              __writeback_inodes_wb
              writeback_sb_inodes
              __writeback_single_inode
              do_writepages
              xfs_vm_writepages
              write_cache_pages
   - 10.06% __libc_pwrite
        entry_SYSCALL_64_fastpath
        sys_pwrite64
        vfs_write
        __vfs_write
        xfs_file_write_iter
        xfs_file_buffered_aio_write
      - generic_perform_write
         - 5.51% xfs_vm_write_begin
            - 4.94% grab_cache_page_write_begin
                 pagecache_get_page
              0.57% __block_write_begin
                 create_page_buffers
                 create_empty_buffers
                 _raw_spin_lock
                 __pv_queued_spin_lock_slowpath
         - 4.88% xfs_vm_write_end
              generic_write_end
              block_write_end
              __block_commit_write.isra.29
              mark_buffer_dirty
              __set_page_dirty

-Dave.
-- 
Dave Chinner
david@fromorbit.com

[toc] | [prev] | [next] | [standalone]


#1463314 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2016-08-16 03:00 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s6ATv-4sZ-11@gated-at.bofh.it>
In reply to#1463308
On Mon, Aug 15, 2016 at 5:38 PM, Dave Chinner <david@fromorbit.com> wrote:
>
> Same in 4.7 (flat profile numbers climbed higher after this
> snapshot was taken, as can be seen by the callgraph numbers):

Ok, so it's not the zone-vs-node thing.  It's just that nobody has
looked at that load in recent times.

Where "recent" may be years, of course.

                   Linus

[toc] | [prev] | [next] | [standalone]


#1463307 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromDave Chinner <david@fromorbit.com>
Date2016-08-16 02:40 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s6AAa-4mv-3@gated-at.bofh.it>
In reply to#1463272
On Mon, Aug 15, 2016 at 04:20:55PM -0700, Linus Torvalds wrote:
> On Mon, Aug 15, 2016 at 3:42 PM, Dave Chinner <david@fromorbit.com> wrote:
> >
> >   31.18%  [kernel]  [k] __pv_queued_spin_lock_slowpath
> >    9.90%  [kernel]  [k] copy_user_generic_string
> >    3.65%  [kernel]  [k] __raw_callee_save___pv_queued_spin_unlock
> >    2.62%  [kernel]  [k] __block_commit_write.isra.29
> >    2.26%  [kernel]  [k] _raw_spin_lock_irqsave
> >    1.72%  [kernel]  [k] _raw_spin_lock
> 
> Ok, this is more like it.
> 
> I'd still like to see it on raw hardware, just to see if we may have a
> bug in the PV code. Because that code has been buggy before. I
> *thought* we fixed it, but ...
> 
> In fact, you don't even need to do it outside of virtualization, but
> with paravirt disabled (so that it runs the native non-pv locking in
> the virtual machine).
> 
> >    36.60%     0.00%  [kernel]            [k] kswapd
> >    - 30.29% kswapd
> >       - 30.23% shrink_node
> >          - 30.07% shrink_node_memcg.isra.75
> >             - 30.15% shrink_inactive_list
> >                - 29.49% shrink_page_list
> >                   - 22.79% __remove_mapping
> >                      - 22.27% _raw_spin_lock_irqsave
> >                           __pv_queued_spin_lock_slowpath
> 
> How I dislike the way perf shows the call graph data... Just last week
> I was talking to Arnaldo about how to better visualize the cost of
> spinlocks, because the normal way "perf" shows costs is so nasty.

Do not change it - it's the way call graph profiles have been
presented for the past 20 years. I hate it when long standing
conventions are changed because one person doesn't like them and
everyone else has to relearn skills the haven't had to think about
for years....

> What happens is that you see that 36% of CPU time is attributed to
> kswapd, and then you can drill down and see where that 36% comes from.
> So far so good, and that's what perf does fairly well.
> 
> But then when you find the spinlock, you actually want to go the other
> way, and instead ask it to show "who were the callers to this routine
> and what were the percentages", so that you can then see whether (for
> example) it's just that __remove_mapping() use that contends with
> itself, or whether it's contending with the page additions or
> whatever..

Um, perf already does that:

-   31.55%    31.55%  [kernel]            [k] __pv_queued_spin_lock_slowpath
   - 19.83% ret_from_fork
      - kthread
         - 18.55% kswapd
              shrink_node
              shrink_node_memcg.isra.75
              shrink_inactive_list
           1.76% worker_thread
              process_one_work
              wb_workfn 
              wb_writeback
              __writeback_inodes_wb
              writeback_sb_inodes         
              __writeback_single_inode
              do_writepages
              xfs_vm_writepages
              write_cache_pages
              xfs_do_writepage
   + 5.95% __libc_pwrite

I have that right here because *it's a view of the profile I've
already looked at*. I didn't post it because, well, it's shorter to
simply say "contention is from in kswapd".

> So what I'd like to see (and this is where it becomes *so* much more
> useful to be able to recreate it myself so that I can play with the
> perf data several different ways) is to see what the profile looks
> like in that spinlocked region.

Boot your machine with "fake_numa=4", and play till you heart is
content. That's all I do with my test VMs to make them exercise NUMA
paths.

> None of this code is all that new, which is annoying. This must have
> gone on forever,

Yes, it has been. Just worse than I've notice before, probably
because of all the stuff put under the tree lock in the past couple
of years.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

[toc] | [prev] | [next] | [standalone]


#1463344 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2016-08-16 04:00 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s6BPz-55j-7@gated-at.bofh.it>
In reply to#1463307
On Mon, Aug 15, 2016 at 5:19 PM, Dave Chinner <david@fromorbit.com> wrote:
>
>> None of this code is all that new, which is annoying. This must have
>> gone on forever,
>
> Yes, it has been. Just worse than I've notice before, probably
> because of all the stuff put under the tree lock in the past couple
> of years.

So this is where a good profile can matter.

Particularly if it's all about kswapd, and all the contention is just
from __remove_mapping(), what should matter is the "all the stuff"
added *there* and absolutely nowhere else.

Sadly (well, not for me), in my profiles I have

 --3.37%--kswapd
   |
    --3.36%--shrink_node
      |
      |--2.88%--shrink_node_memcg
      |  |
      |   --2.87%--shrink_inactive_list
      |     |
      |     |--2.55%--shrink_page_list
      |     |  |
      |     |  |--0.84%--__remove_mapping
      |     |  |  |
      |     |  |  |--0.37%--__delete_from_page_cache
      |     |  |  |  |
      |     |  |  |   --0.21%--radix_tree_replace_clear_tags
      |     |  |  |     |
      |     |  |  |      --0.12%--__radix_tree_lookup
      |     |  |  |
      |     |  |   --0.23%--_raw_spin_lock_irqsave
      |     |  |     |
      |     |  |      --0.11%--queued_spin_lock_slowpath
      |     |  |
   ................


which is rather different from your 22% spin-lock overhead.

Anyway, including the direct reclaim call paths gets
__remove_mapping() a bit higher, and _raw_spin_lock_irqsave climbs to
0.26%. But perhaps more importlantly, looking at what __remove_mapping
actually *does* (apart from the spinlock) gives us:

 - inside remove_mapping itself (0.11% on its own - flat cost, no
child accounting)

    48.50 │       lock   cmpxchg %edx,0x1c(%rbx)

    so that's about 0.05%

 - 0.40% __delete_from_page_cache (0.22%
radix_tree_replace_clear_tags, 0.13%__radix_tree_lookup)

 - 0.06% workingset_eviction()

so I'm not actually seeing anything *new* expensive in there. The
__delete_from_page_cache() overhead may have changed a bit with the
tagged tree changes, but this doesn't look like memcg.

But we clearly have very different situations.

What does your profile show for when you actually dig into
__remove_mapping() itself?, Looking at your flat profile, I'm assuming
you get

   1.31%  [kernel]  [k] __radix_tree_lookup
   1.22%  [kernel]  [k] radix_tree_tag_set
   1.14%  [kernel]  [k] __remove_mapping

which is higher (but part of why my percentages are lower is that I
have that "50% CPU used for encryption" on my machine).

But I'm not seeing anything I'd attribute to "all the stuff added".
For example, originally I would have blamed memcg, but that's not
actually in this path at all.

I come back to wondering whether maybe you're hitting some PV-lock problem.

I know queued_spin_lock_slowpath() is ok. I'm not entirely sure
__pv_queued_spin_lock_slowpath() is.

So I'd love to see you try the non-PV case, but I also think it might
be interesting to see what the instruction profile for
__pv_queued_spin_lock_slowpath() itself is. They share a lot of code
(there's some interesting #include games going on to make
queued_spin_lock_slowpath() actually *be*
__pv_queued_spin_lock_slowpath() with some magic hooks), but there
might be issues.

For example, if you run a virtual 16-core system on a physical machine
that then doesn't consistently give 16 cores to the virtual machine,
you'll get no end of hiccups.

Because as mentioned, we've had bugs ("performance anomalies") there before.

               Linus

[toc] | [prev] | [next] | [standalone]


#1464197 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromDave Chinner <david@fromorbit.com>
Date2016-08-17 00:10 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s6UIx-r4-1@gated-at.bofh.it>
In reply to#1463344
On Mon, Aug 15, 2016 at 06:51:42PM -0700, Linus Torvalds wrote:
> Anyway, including the direct reclaim call paths gets
> __remove_mapping() a bit higher, and _raw_spin_lock_irqsave climbs to
> 0.26%. But perhaps more importlantly, looking at what __remove_mapping
> actually *does* (apart from the spinlock) gives us:
> 
>  - inside remove_mapping itself (0.11% on its own - flat cost, no
> child accounting)
> 
>     48.50 │       lock   cmpxchg %edx,0x1c(%rbx)
> 
>     so that's about 0.05%
> 
>  - 0.40% __delete_from_page_cache (0.22%
> radix_tree_replace_clear_tags, 0.13%__radix_tree_lookup)
> 
>  - 0.06% workingset_eviction()
> 
> so I'm not actually seeing anything *new* expensive in there. The
> __delete_from_page_cache() overhead may have changed a bit with the
> tagged tree changes, but this doesn't look like memcg.
> 
> But we clearly have very different situations.
> 
> What does your profile show for when you actually dig into
> __remove_mapping() itself?, Looking at your flat profile, I'm assuming
> you get

-   22.26%     0.93%  [kernel]          [k] __remove_mapping
   - 3.86% __remove_mapping
      - 18.35% _raw_spin_lock_irqsave
           __pv_queued_spin_lock_slowpath
        1.32% __delete_from_page_cache
      - 0.92% _raw_spin_unlock_irqrestore
           __raw_callee_save___pv_queued_spin_unlock

And the instruction level profile:

.....
       �       xor    %ecx,%ecx
       �       mov    %rax,%r15
  0.39 �       mov    $0x2,%eax
       �       lock   cmpxchg %ecx,0x1c(%rbx)
 32.56 �       cmp    $0x2,%eax
       �     � jne    12e
       �       mov    0x20(%rbx),%rax
       �       lea    -0x1(%rax),%rdx
  0.39 �       test   $0x1,%al
       �       cmove  %rbx,%rdx
       �       mov    (%rdx),%rax
  0.39 �       test   $0x10,%al
       �     � jne    127
       �       mov    (%rbx),%rcx
       �       shr    $0xf,%rcx
       �       and    $0x1,%ecx
       �     � jne    14a
       �       mov    0x68(%r14),%rax
 36.03 �       xor    %esi,%esi
       �       test   %r13b,%r13b
       �       mov    0x50(%rax),%rdx
  1.16 �     � jne    e8
  0.96 � a9:   mov    %rbx,%rdi
.....

Indicates most time on the cmpxchg for the page ref followed by the
grabbing on the ->freepage op vector:

	freepage = mapping->a_ops->freepage;

> I come back to wondering whether maybe you're hitting some PV-lock problem.
> 
> I know queued_spin_lock_slowpath() is ok. I'm not entirely sure
> __pv_queued_spin_lock_slowpath() is.

It's the same code AFAICT, except the pv version jumps straight to
the "queue" case.

> So I'd love to see you try the non-PV case, but I also think it might
> be interesting to see what the instruction profile for
> __pv_queued_spin_lock_slowpath() itself is. They share a lot of code
> (there's some interesting #include games going on to make
> queued_spin_lock_slowpath() actually *be*
> __pv_queued_spin_lock_slowpath() with some magic hooks), but there
> might be issues.

  0.03 �       data16 data16 data16 xchg %ax,%ax
       �       push   %rbp
  0.00 �       mov    %rsp,%rbp
  0.01 �       push   %r15
       �       push   %r14
       �       push   %r13
  0.01 �       push   %r12
       �       mov    $0x18740,%r12
       �       push   %rbx
       �       mov    %rdi,%rbx
       �       sub    $0x10,%rsp
       �       add    %gs:0x7ef0d0e0(%rip),%r12
       �       movslq 0xc(%r12),%rax
  0.02 �       mov    %gs:0x7ef0d0db(%rip),%r15d
       �       add    $0x1,%r15d
       �       shl    $0x12,%r15d
       �       lea    0x1(%rax),%edx
  0.01 �       mov    %edx,0xc(%r12)
       �       mov    %eax,%edx
       �       shl    $0x4,%rax
       �       add    %rax,%r12
       �       shl    $0x10,%edx
       �       movq   $0x0,(%r12)
  0.02 �       or     %edx,%r15d
       �       mov    %gs:0x7ef0d0ad(%rip),%eax
  0.00 �       movl   $0x0,0x8(%r12)
  0.01 �       mov    %eax,0x40(%r12)
       �       movb   $0x0,0x44(%r12)
       �       mov    (%rdi),%eax
  0.88 �       test   %ax,%ax
       �     � jne    8f
  0.02 �       mov    $0x1,%edx
       �       lock   cmpxchg %dl,(%rdi)
  0.38 �       test   %al,%al
       �     � je     14a
  0.02 � 8f:   mov    %r15d,%eax
       �       shr    $0x10,%eax
       �       xchg   %ax,0x2(%rbx)
  2.07 �       shl    $0x10,%eax
       �       test   %eax,%eax
       �     � jne    171
       �       movq   $0x0,-0x30(%rbp)
  0.02 � ac:   movzbl 0x44(%r12),%eax
  0.97 �       mov    $0x1,%r13d
       �       mov    $0x100,%r14d
       �       cmp    $0x2,%al
       �       sete   %al
       �       movzbl %al,%eax
       �       mov    %rax,-0x38(%rbp)
  0.00 � ca:   movb   $0x0,0x44(%r12)
  0.00 �       mov    $0x8000,%edx
       �       movb   $0x1,0x1(%rbx)
       �     � jmp    e6
  0.04 � db:   pause
  8.04 �       sub    $0x1,%edx
       �     � je     229
       � e6:   movzbl (%rbx),%eax
  7.54 �       test   %al,%al
       �     � jne    db
  0.10 �       mov    %r14d,%eax
  0.06 �       lock   cmpxchg %r13w,(%rbx)
  2.93 ?       cmp    $0x100,%ax
       �     � jne    db
       � fc:   mov    (%rbx),%edx
  0.37 �       mov    $0x1,%ecx
       �       or     $0x1,%edx
       �     � jmp    114
  0.01 �108:   mov    %edx,%eax
       �       lock   cmpxchg %ecx,(%rbx)
  0.26 �       cmp    %edx,%eax
       �     � je     14a
       �       mov    %eax,%edx
       �114:   mov    %edx,%eax
  0.00 �       xor    %ax,%ax
       �       cmp    %r15d,%eax
       �     � je     108
  0.01 �       cmpq   $0x0,-0x30(%rbp)
       ?       movb   $0x1,(%rbx)
       �     � je     251
       �12c:   mov    -0x30(%rbp),%rsi
  0.01 �       mov    $0x1,%eax
       �       mov    $0x2,%edx
       �       movl   $0x1,0x8(%rsi)
  0.11 �       lock   cmpxchg %dl,0x44(%rsi)
  2.34 �       cmp    $0x1,%al
       �     � je     160
       �14a:   decl   %gs:0x7ef1b5bb(%rip)
  0.02 �       add    $0x10,%rsp
       �       pop    %rbx
       �       pop    %r12
  0.00 �       pop    %r13
       �       pop    %r14
       �       pop    %r15
       �       pop    %rbp
       �     � retq
       �160:   mov    -0x30(%rbp),%rsi
       �       movb   $0x3,(%rbx)
       �       mov    %rbx,%rdi
       �       callq  0xffffffff810fcf90
       �     � jmp    14a
       �171:   lea    0x44(%r12),%r14
       �       mov    %rax,%r13
       �       shr    $0x12,%eax
       �       shr    $0xc,%r13
       �       sub    $0x1,%eax
       �       and    $0x30,%r13d
       �       cltq
       �       add    $0x18740,%r13
       ?       add    -0x7d8164c0(,%rax,8),%r13
  0.03 �       mov    %r12,0x0(%r13)
  0.38 �19c:   mov    $0x8000,%eax
       �     � jmp    1b7
  0.04 �1a3:   test   %al,%al
       �     � jne    1b0
       �       movzbl 0x44(%r13),%edx
  1.66 �       test   %dl,%dl
       �     � jne    1f1
  1.75 �1b0:   pause
 64.57 �       sub    $0x1
  0.04 �    �  mov    0x8(%r12),%eax
  0.03 �    �  test   %eax,%eax
       �    �� jne    1d4
       �1c9:�  pause
       �    �  mov    0x8(%r12),%eax
       �    �  test   %eax,%eax
       �    �� je     1c9
       �1d4:�  mov    (%r12),%rax
       �    �  test   %rax,%rax
       �    �  mov    %rax,-0x30(%rbp)
  0.05 �    �� je     ac
       �    �  mov    -0x30(%rbp),%rax
       �    �  prefet (%rax)
  0.25 �    �� jmpq   ac
       �1f1:�  mov    $0x1,%eax
       �    �  xchg   %al,0x44(%r12)
       �    �  mov    0x8(%r12),%eax
       �    �  test   %eax,%eax
       �    �� jne    213
       �    �  mov    %r14,%rdi
       �    �  mov    $0x1,%esi
       �    �  callq  0xffffffff8109f7a0
       �    �  xchg   %ax,%ax
       �213:�  mov    $0x1,%eax
       �    �  xor    %edi,%edi
       �    �  lock   cmpxchg %dil,(%r14)
       �    �  mov    0x8(%r12),%eax
       �    �� jmpq   19c
       �229:�  cmpq   $0x0,-0x38(%rbp)
       �    �  movb   $0x0,0x1(%rbx)
       �    �� je     276
       �234:�  movb   $0x1,0x44(%r12)
       �    �  mov    $0x3,%esi
       �    �  mov    %rbx,%rdi
       �    �  callq  0xffffffff8109f7a0
       �    �  xchg   %ax,%ax
       �    �  movzbl (%rbx),%eax
       �    �� jmpq   ca
       �251:�  mov    (%r12),%rax
  0.14 �    �  test   %rax,%rax
       �    �  mov    %rax,-0x30(%rbp)
       �    �� jne    12c
       �262:�  pause
  0.31 �    �  mov    (%r12),%rax
       �    �  test   %rax,%rax
       �    �� je     262
       �    �  mov    %rax,-0x30(%rbp)
       �    �� jmpq   12c
       �276:?  mov    %r12,%rsi
       �    �  mov    %rbx,%rdi
       �    �  callq  0xffffffff810fcf90
       �    �  mov    %rax,-0x38(%rbp)
       �    �  mov    $0x3,%eax
       �    �  xchg   %al,(%rbx)
       �    �  test   %al,%al
       �    �� jne    234
       �    �  mov    -0x38(%rbp),%rax
       �    �  movb   $0x1,(%rbx)
       �    �  movq   $0x0,(%rax)
       �    ���jmpq   fc            

> For example, if you run a virtual 16-core system on a physical machine
> that then doesn't consistently give 16 cores to the virtual machine,
> you'll get no end of hiccups.

I learnt that lesson 6-7 years ago when I first started doing
baseline benchmarking to compare bare metal to virtualised IO
performance.

-Dave.
-- 
Dave Chinner
david@fromorbit.com

[toc] | [prev] | [next] | [standalone]


#1464235 — Re: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2016-08-17 01:30 +0200
SubjectRe: [LKP] [lkp] [xfs] 68a9f5e700: aim7.jobs-per-min -13.6% regression
Message-ID<s6VXY-19x-1@gated-at.bofh.it>
In reply to#1464197
On Tue, Aug 16, 2016 at 3:02 PM, Dave Chinner <david@fromorbit.com> wrote:
>>
>> What does your profile show for when you actually dig into
>> __remove_mapping() itself?, Looking at your flat profile, I'm assuming
>> you get
>
> -   22.26%     0.93%  [kernel]          [k] __remove_mapping
>    - 3.86% __remove_mapping
>       - 18.35% _raw_spin_lock_irqsave
>            __pv_queued_spin_lock_slowpath
>         1.32% __delete_from_page_cache
>       - 0.92% _raw_spin_unlock_irqrestore
>            __raw_callee_save___pv_queued_spin_unlock

Ok, that's all very consistent with my profiles, except - obviously -
for the crazy spinlock thing.

One difference is that your unlock has that PV unlock thing - on raw
hardware it's just a single store. But I don't think I saw the
unlock_slowpath in there.

There's nothing really expensive going on there that I can tell.

> And the instruction level profile:

Yup. The bulk is in the cmpxchg and a cache miss (it just shows up in
the instruction after it: you can use "cycles:pp" to get perf to
actually try to fix up the blame to the instruction that _causes_
things rather than the instruction following, but in this case it's
all trivial).

> It's the same code AFAICT, except the pv version jumps straight to
> the "queue" case.

Yes. Your profile looks perfectly fine. Most of the profile is rigth
after the 'pause', which you'd expect.

From a quick look, it seems like only about 2/3rd of the time is
actually spent in the "pause" loop, but the control flow is complex
enough that maybe I didn't follow it right. The native case is
simpler. But since I suspect that it's not so much about the
spinlocked region being too costly, but just about locking too damn
much), that 2/3rds actually makes sense: it's not that it's
necessarily spinning waiting for the lock all that long in any
individual case, it's just that the spin_lock code is called so much.

So I still kind of just blame kswapd, rather than any new expense. It
would be interesting to hear if Mel is right about that kswapd
sleeping change between 4.6 and 4.7..

               Linus

[toc] | [prev] | [next] | [standalone]


Page 3 of 5 — ← Prev page 1 2 [3] 4 5  Next page →

Back to top | Article view | linux.kernel


csiph-web