Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] i2c: omap: re-factor omap_i2c_init function
From: Felipe Balbi @ 2012-10-25 10:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAM=Q2ctcxO2eFFBDdF_Mwt1bm34pj5hvJW4AS6V-GQVTVGz98Q@mail.gmail.com>

Hi,

On Thu, Oct 25, 2012 at 03:04:29PM +0530, Shubhrajyoti Datta wrote:
> On Thu, Oct 25, 2012 at 12:06 PM, Felipe Balbi <balbi@ti.com> wrote:
> 
> [...]
> >> +      * Don't write to this register if the IE state is 0 as it can
> >> +      * cause deadlock.
> >> +      */
> >> +     if (dev->iestate)
> >> +             omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> >> +}
> >> +
> >>  static int omap_i2c_init(struct omap_i2c_dev *dev)
> >>  {
> >> -     u16 psc = 0, scll = 0, sclh = 0, buf = 0;
> >> +     u16 psc = 0, scll = 0, sclh = 0;
> >>       u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
> >>       unsigned long fclk_rate = 12000000;
> >>       unsigned long timeout;
> >> @@ -337,11 +358,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
> >>                        * REVISIT: Some wkup sources might not be needed.
> >>                        */
> >>                       dev->westate = OMAP_I2C_WE_ALL;
> >> -                     omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
> >> -                                                     dev->westate);
> >
> > remove the comment too since now that's done by some other function ?
> 
> The comment is applicable to the OMAP_I2C_WE_ALL value.
> So I thought it could be kept.
> 
> dont feel strongly though.

I see. that's ok then.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121025/9ddee6e4/attachment.sig>

^ permalink raw reply

* [PATCH 3/8] i2c: omap: fix error checking
From: Felipe Balbi @ 2012-10-25 10:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5087FE07.6090504@amarulasolutions.com>

Hi,

On Wed, Oct 24, 2012 at 04:41:11PM +0200, Michael Trimarchi wrote:
> Hi
> 
> On 10/22/2012 11:46 AM, Felipe Balbi wrote:
> > It's impossible to have Arbitration Lost,
> > Read Overflow, and Tranmist Underflow all
> > asserted at the same time.
> > 
> > Those error conditions are mutually exclusive
> > so what the code should be doing, instead, is
> > check each error flag separataly.
> > 
> > Signed-off-by: Felipe Balbi <balbi@ti.com>
> > ---
> >  drivers/i2c/busses/i2c-omap.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> > index bea0277..e0eab38 100644
> > --- a/drivers/i2c/busses/i2c-omap.c
> > +++ b/drivers/i2c/busses/i2c-omap.c
> > @@ -587,9 +587,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
> >  		goto err_i2c_init;
> >  	}
> >  
> > -	/* We have an error */
> > -	if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR |
> > -			    OMAP_I2C_STAT_XUDF)) {
> > +	if ((dev->cmd_err & OMAP_I2C_STAT_AL)
> > +			|| (dev->cmd_err & OMAP_I2C_STAT_ROVR)
> > +			|| (dev->cmd_err & OMAP_I2C_STAT_XUDF)) {
> 
> Sorry, what is the difference? I didn't understand the optimisation
> and why now is more clear. Can you just add a comment?

semantically they're not the same, right ? We want to check if each of
those bits are set, not if all of them are set together.

my 2 cents.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121025/f3659a9c/attachment.sig>

^ permalink raw reply

* OMAP baseline test results for v3.7-rc1
From: Felipe Balbi @ 2012-10-25 10:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAORVsuV9_4oc6+voEM9PkqzkXKHipor5XJqaXfDNxAWLofXcxg@mail.gmail.com>

Hi,

On Tue, Oct 23, 2012 at 09:23:03PM +0200, Jean Pihet wrote:
> On Tue, Oct 23, 2012 at 9:19 PM, Paul Walmsley <paul@pwsan.com> wrote:
> > On Mon, 22 Oct 2012, Jean Pihet wrote:
> >
> >> On Mon, Oct 22, 2012 at 6:12 PM, Jean Pihet <jean.pihet@newoldbits.com> wrote:
> >>
> >> > Do you have CPU_IDLE enabled?
> >> FYI the issue is not present with CPU_IDLE enabled.
> >
> > Hmm, how can you tell?  I thought you weren't able to reproduce it with
> > CPU_IDLE disabled either?
> I could not reproduce the issue, with and without CPU_IDLE enabled.
> What puzzles me is that the PM QoS code only has influence on the
> states chosen by cpuidle, so the change should not have any impact
> with CPU_IDLE enabled. I reallt need to reproduce the issue.
> Let me try with the same setup as yours (bootloader images,
> omap2pus_defconfig, angstrom roots).

I just sent a patch to fix a bug I found on OMAP4 panda but while
reading this thread again, I think it could be that it's the same bug
which is just easier to reproduce on Paul's setup.

Paul, Aaro, can you see if [1] makes the problem go away ? that would be
another reason to push [1] during this -rc cycle.

[1] http://marc.info/?l=linux-omap&m=135115602407925&w=2

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121025/75fc7df8/attachment-0001.sig>

^ permalink raw reply

* [PATCH v2 2/2] USB: doc: Binding document for ehci-platform driver
From: Sebastian Andrzej Siewior @ 2012-10-25 10:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5088399F.2000102@firmworks.com>

On Wed, Oct 24, 2012 at 08:55:27AM -1000, Mitch Bradley wrote:
> >> So by listing "usb-ehci" in its device ID table, a driver would
> >> essentially be saying that it can handle _all_ USB EHCI controllers.  
> 
> 
> Actually, it means that the driver can handle at least USB EHCI
> controllers that are 100% compatible with the EHCI spec (requiring
> nothing extra).  The driver might be able to handle almost-compatible
> controllers, possibly with the help of additional properties.
> 
> If a DT node lists "usb-ehci" as a "fallback", it's not guaranteed that
> a given version of that driver will work, but it's worth a try in the
> event that no more-specific driver is matched.

Not sure fallback is a good term here. The of parses the compatible from left
to right. If the device specific entry is not found (in the driver) then end
up with usb-ehci. If we need a quirk later on we add the device specific entry
to the driver (which will match before usb-ehci is found) and we could use
this entry to apply the quirk. That way you can apply quirks without touch the
firmware / device tree.

Sebastian

^ permalink raw reply

* [PATCH 0/2] i2c: omap: cleanups
From: Shubhrajyoti D @ 2012-10-25 10:23 UTC (permalink / raw)
  To: linux-arm-kernel

Applies on Felipe's series
http://www.spinics.net/lists/linux-omap/msg79995.html

Tested with Terro sys fix + Felipe's stop sched_clock() during suspend
on omap3630 beagle both idle and suspend.

Functional testing on omap4sdp.


Shubhrajyoti D (2):
  i2c: omap: re-factor omap_i2c_init function
  i2c: omap: make reset a seperate function

 drivers/i2c/busses/i2c-omap.c |   97 +++++++++++++++++++++--------------------
 1 files changed, 49 insertions(+), 48 deletions(-)

-- 
1.7.5.4

^ permalink raw reply

* [PATCH 1/2] i2c: omap: re-factor omap_i2c_init function
From: Shubhrajyoti D @ 2012-10-25 10:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351160586-12306-1-git-send-email-shubhrajyoti@ti.com>

re-factor omap_i2c_init() so that we can re-use it for resume.
While at it also remove the bufstate variable as we write it
in omap_i2c_resize_fifo for every transfer.

Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   71 ++++++++++++++++++----------------------
 1 files changed, 32 insertions(+), 39 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 5e5cefb..3d400b1 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -209,7 +209,6 @@ struct omap_i2c_dev {
 	u16			pscstate;
 	u16			scllstate;
 	u16			sclhstate;
-	u16			bufstate;
 	u16			syscstate;
 	u16			westate;
 	u16			errata;
@@ -285,9 +284,31 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
 	}
 }
 
+static void __omap_i2c_init(struct omap_i2c_dev *dev)
+{
+
+	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+	/* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
+	omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+
+	/* SCL low and high time values */
+	omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+	omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+	if (dev->rev >= OMAP_I2C_REV_ON_3430_3530)
+		omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+	/* Take the I2C module out of reset: */
+	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+	/*
+	 * Don't write to this register if the IE state is 0 as it can
+	 * cause deadlock.
+	 */
+	if (dev->iestate)
+		omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+}
+
 static int omap_i2c_init(struct omap_i2c_dev *dev)
 {
-	u16 psc = 0, scll = 0, sclh = 0, buf = 0;
+	u16 psc = 0, scll = 0, sclh = 0;
 	u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
 	unsigned long fclk_rate = 12000000;
 	unsigned long timeout;
@@ -337,11 +358,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 			 * REVISIT: Some wkup sources might not be needed.
 			 */
 			dev->westate = OMAP_I2C_WE_ALL;
-			omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
-							dev->westate);
 		}
 	}
-	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
 
 	if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) {
 		/*
@@ -426,28 +444,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 		sclh = fclk_rate / (dev->speed * 2) - 7 + psc;
 	}
 
-	/* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
-	omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc);
-
-	/* SCL low and high time values */
-	omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
-	omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
-
-	/* Take the I2C module out of reset: */
-	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
-
 	/* Enable interrupts */
 	dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
 			OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL)  |
 			((dev->fifo_size) ? (OMAP_I2C_IE_RDR |
 				OMAP_I2C_IE_XDR) : 0);
-	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
-	if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
-		dev->pscstate = psc;
-		dev->scllstate = scll;
-		dev->sclhstate = sclh;
-		dev->bufstate = buf;
-	}
+
+	dev->pscstate = psc;
+	dev->scllstate = scll;
+	dev->sclhstate = sclh;
+
+	__omap_i2c_init(dev);
+
 	return 0;
 }
 
@@ -1268,23 +1276,8 @@ static int omap_i2c_runtime_resume(struct device *dev)
 {
 	struct omap_i2c_dev *_dev = dev_get_drvdata(dev);
 
-	if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
-		omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
-		omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
-		omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
-		omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
-		omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
-		omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
-		omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
-		omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
-	}
-
-	/*
-	 * Don't write to this register if the IE state is 0 as it can
-	 * cause deadlock.
-	 */
-	if (_dev->iestate)
-		omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
+	if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
+		__omap_i2c_init(_dev);
 
 	return 0;
 }
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 2/2] i2c: omap: make reset a seperate function
From: Shubhrajyoti D @ 2012-10-25 10:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351160586-12306-1-git-send-email-shubhrajyoti@ti.com>

Implement reset as a seperate function.
This will enable us to make sure that we don't do the
calculation again on every transfer.
Also at probe the reset is not added as the hwmod is doing that
for us.

Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   28 ++++++++++++++++++----------
 1 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 3d400b1..5a87ff9 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -306,15 +306,9 @@ static void __omap_i2c_init(struct omap_i2c_dev *dev)
 		omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
 }
 
-static int omap_i2c_init(struct omap_i2c_dev *dev)
+static int omap_i2c_reset(struct omap_i2c_dev *dev)
 {
-	u16 psc = 0, scll = 0, sclh = 0;
-	u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
-	unsigned long fclk_rate = 12000000;
 	unsigned long timeout;
-	unsigned long internal_clk = 0;
-	struct clk *fclk;
-
 	if (dev->rev >= OMAP_I2C_OMAP1_REV_2) {
 		/* Disable I2C controller before soft reset */
 		omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
@@ -360,6 +354,17 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 			dev->westate = OMAP_I2C_WE_ALL;
 		}
 	}
+	return 0;
+}
+
+static int omap_i2c_init(struct omap_i2c_dev *dev)
+{
+	u16 psc = 0, scll = 0, sclh = 0;
+	u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
+	unsigned long fclk_rate = 12000000;
+	unsigned long internal_clk = 0;
+	struct clk *fclk;
+
 
 	if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) {
 		/*
@@ -592,7 +597,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 	if (timeout == 0) {
 		dev_err(dev->dev, "controller timed out\n");
 		ret = -ETIMEDOUT;
-		omap_i2c_init(dev);
+		omap_i2c_reset(dev);
+		__omap_i2c_init(dev);
 		goto out;
 	}
 
@@ -603,7 +609,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 			|| (dev->cmd_err & OMAP_I2C_STAT_ROVR)
 			|| (dev->cmd_err & OMAP_I2C_STAT_XUDF)) {
 		ret = -EIO;
-		omap_i2c_init(dev);
+		omap_i2c_reset(dev);
+		__omap_i2c_init(dev);
 		goto out;
 	}
 
@@ -621,7 +628,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 			return 0;
 
 		ret = -EREMOTEIO;
-		omap_i2c_init(dev);
+		omap_i2c_reset(dev);
+		__omap_i2c_init(dev);
 	}
 
 out:
-- 
1.7.5.4

^ permalink raw reply related

* [RFC PATCH 00/13] sched: Integrating Per-entity-load-tracking with the core scheduler
From: Preeti U Murthy @ 2012-10-25 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset uses the per-entity-load-tracking patchset which will soon be
available in the kernel.It is based on the tip/master tree before the
(HEAD at b654f92c06e562c)integration of per-entity-load-tracking patchset.
The first 8 latest patches of sched:per-entity-load-tracking alone have
been imported to the tree from the quilt series of Peter(when they were
present) to avoid the complexities of task groups and to hold back the
optimizations of this patchset for now.This patchset is based at this level.
Refer https://lkml.org/lkml/2012/10/12/9.This series is a continuation
of the patchset in this link.

This patchset is an attempt to begin the integration of PJT's
metric with the load balancer in a step wise fashion,and progress based
on the consequences.This patchset has been tested with the config excluding
CONFIG_FAIR_GROUP_SCHED.

The following issues have been considered towards this:
[NOTE:an x% task referred to in the logs and below is calculated over a
duty cycle of 10ms.]

1.Consider a scenario,where there are two 10% tasks running on a cpu.The
  present code will consider the load on this queue to be 2048,while
  using PJT's metric the load is calculated to be <1000,rarely exceeding this
  limit.Although the tasks are not contributing much to the cpu load,they are
  decided to be moved by the scheduler.

  But one could argue that 'not moving one of these tasks could throttle
  them.If there was an idle cpu,perhaps we could have moved them'.While the
  power save mode would have been fine with not moving the task,the
  performance mode would prefer not to throttle the tasks.We could strive
  to strike a balance by making this decision tunable with certain parameters.
  This patchset includes such tunables.This issue is addressed in Patch[1/2].

  *The advantage of this behavior of PJT's metric has been demonstrated via
   an experiment*.Please see the reply to this cover letter to be posted right
   away.

2.We need to be able to do this cautiously,as the scheduler code is too
  complex.This patchset is an attempt to begin the integration of PJT's
  metric with the load balancer in a step wise fashion,and progress based on
  the consequences.
  *What this patchset essentially does is in two primary places of the
   scheduler,PJT's metric has replaced the existing metric to make decisions for load
   balancing*.
  1.load_balance()
  2.select_task_rq_fair()

  This description of the patches are below:

         Patch[1/13]: This patch aims@detecting short running tasks and
	 prevent their movement.In update_sg_lb_stats,dismiss a sched group
         as a candidate for load balancing,if load calculated by PJT's metric
	 says that the average load on the sched_group <= 1024+(.15*1024).
	 This is a tunable,which can be varied after sufficient experiments.

         Patch[2/13]:In the current scheduler greater load would be analogous
         to more number of tasks.Therefore when the busiest group is picked
         from the sched domain in update_sd_lb_stats,only the loads of the
         groups are compared between them.If we were to use PJT's metric,a
         higher load does not necessarily mean more number of tasks.This
	 patch addresses this issue.

	 Patch[3/13] to Patch[13/13] : Replacement of the existing metrics
	 deciding load balancing and selecting a runqueue for load
         placement,with the PJT's metric and subsequent usage of PJT's metric
         for schduling.

3.The Primary advantage that I see in integrating PJT's metric with the core
  scheduler is listed below:

  1. Excluding short running tasks from being candidates for load balancing.
     This would avoid unnecessary migrations when the CPU is not sufficiently
     loaded.This advantage has been portrayed in the results of the
     experiment.

     Run the workload attached.There are 8 threads spwaned each being 10%
     tasks.
     The number of migrations was measured from /proc/schedstat

     Machine: 1 socket 4 core pre-nehalem.

     Experimental Setup:
     cat /proc/schedstat > stat_initial
     gcc -Wall -Wshadow -lpthread  -o test test.c
     cat /proc/schedstat > stat_final
     The difference in the number of pull requests from both these files have
     been calculated and are as below:

     Observations:
					With_Patchset	Without_patchset
     ---------------------------------------------------------------------
     Average_number_of_migrations	    0		 46
     Average_number_of_records/s          9,71,114	9,45,158

  With more memory intensive workloads, a higher difference in the number of
  migrations is seen without any performance compromise.

---

Preeti U Murthy (13):
      sched:Prevent movement of short running tasks during load balancing
      sched:Pick the apt busy sched group during load balancing
      sched:Decide whether there be transfer of loads based on the PJT's metric
      sched:Decide group_imb using PJT's metric
      sched:Calculate imbalance using PJT's metric
      sched:Changing find_busiest_queue to use PJT's metric
      sched:Change move_tasks to use PJT's metric
      sched:Some miscallaneous changes in load_balance
      sched:Modify check_asym_packing to use PJT's metric
      sched:Modify fix_small_imbalance to use PJT's metric
      sched:Modify find_idlest_group to use PJT's metric
      sched:Modify find_idlest_cpu to use PJT's metric
      sched:Modifying wake_affine to use PJT's metric


 kernel/sched/fair.c |  262 ++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 186 insertions(+), 76 deletions(-)

-- 
Preeti U Murthy

^ permalink raw reply

* [RFC PATCH 01/13] sched:Prevent movement of short running tasks during load balancing
From: Preeti U Murthy @ 2012-10-25 10:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Prevent sched groups with low load as tracked by PJT's metrics
from being candidates of the load balance routine.This metric is chosen to be
1024+15%*1024.But using PJT's metrics it has been observed that even when
three 10% tasks are running,the load sometimes does not exceed this
threshold.The call should be taken if the tasks can afford to be throttled.

This is why an additional metric has been included,which can determine how
long we can tolerate tasks not being moved even if the load is low.

Signed-off-by:  Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index dbddcf6..e02dad4 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4188,6 +4188,7 @@ struct sd_lb_stats {
  */
 struct sg_lb_stats {
 	unsigned long avg_load; /*Avg load across the CPUs of the group */
+	u64 avg_cfs_runnable_load; /* Equivalent of avg_load but calculated using PJT's metric */
 	unsigned long group_load; /* Total load over the CPUs of the group */
 	unsigned long sum_nr_running; /* Nr tasks running in the group */
 	unsigned long sum_weighted_load; /* Weighted load of group's tasks */
@@ -4504,6 +4505,7 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 	unsigned long load, max_cpu_load, min_cpu_load;
 	unsigned int balance_cpu = -1, first_idle_cpu = 0;
 	unsigned long avg_load_per_task = 0;
+	u64 group_load = 0; /* computed using PJT's metric */
 	int i;
 
 	if (local_group)
@@ -4548,6 +4550,7 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 		if (idle_cpu(i))
 			sgs->idle_cpus++;
 
+		group_load += cpu_rq(i)->cfs.runnable_load_avg;
 		update_sg_numa_stats(sgs, rq);
 	}
 
@@ -4572,6 +4575,19 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 	sgs->avg_load = (sgs->group_load*SCHED_POWER_SCALE) / group->sgp->power;
 
 	/*
+	 * Check if the sched group has not crossed the threshold.
+	 *
+	 * Also check if the sched_group although being within the threshold,is not
+	 * queueing too many tasks.If yes to both,then make it an
+	 * invalid candidate for load balancing
+	 *
+	 * The below condition is included as a tunable to meet performance and power needs
+	 */
+	sgs->avg_cfs_runnable_load = (group_load * SCHED_POWER_SCALE) / group->sgp->power;
+	if (sgs->avg_cfs_runnable_load <= 1178 && sgs->sum_nr_running <= 2)
+		sgs->avg_cfs_runnable_load = 0;
+
+	/*
 	 * Consider the group unbalanced when the imbalance is larger
 	 * than the average weight of a task.
 	 *

^ permalink raw reply related

* [RFC PATCH 02/13] sched:Pick the apt busy sched group during load balancing
From: Preeti U Murthy @ 2012-10-25 10:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

If a sched group has passed the test for sufficient load in
update_sg_lb_stats,to qualify for load balancing,then PJT's
metrics has to be used to qualify the right sched group as the busiest group.

The scenario which led to this patch is shown below:
Consider Task1 and Task2 to be a long running task
and Tasks 3,4,5,6 to be short running tasks

			Task3
			Task4
Task1			Task5
Task2			Task6
------			------
SCHED_GRP1		SCHED_GRP2

Normal load calculator would qualify SCHED_GRP2 as
the candidate for sd->busiest due to the following loads
that it calculates.

SCHED_GRP1:2048
SCHED_GRP2:4096

Load calculator would probably qualify SCHED_GRP1 as the candidate
for sd->busiest due to the following loads that it calculates

SCHED_GRP1:3200
SCHED_GRP2:1156

This patch aims to strike a balance between the loads of the
group and the number of tasks running on the group to decide the
busiest group in the sched_domain.

This means we will need to use the PJT's metrics but with an
additional constraint.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |   25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index e02dad4..aafa3c1 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -165,7 +165,8 @@ void sched_init_granularity(void)
 #else
 # define WMULT_CONST	(1UL << 32)
 #endif
-
+#define NR_THRESHOLD 2
+#define LOAD_THRESHOLD 1
 #define WMULT_SHIFT	32
 
 /*
@@ -4169,6 +4170,7 @@ struct sd_lb_stats {
 	/* Statistics of the busiest group */
 	unsigned int  busiest_idle_cpus;
 	unsigned long max_load;
+	u64 max_sg_load; /* Equivalent of max_load but calculated using pjt's metric*/
 	unsigned long busiest_load_per_task;
 	unsigned long busiest_nr_running;
 	unsigned long busiest_group_capacity;
@@ -4628,8 +4630,24 @@ static bool update_sd_pick_busiest(struct lb_env *env,
 				   struct sched_group *sg,
 				   struct sg_lb_stats *sgs)
 {
-	if (sgs->avg_load <= sds->max_load)
-		return false;
+	/* Use PJT's metrics to qualify a sched_group as busy
+ 	 *
+ 	 * But a low load sched group may be queueing up many tasks
+ 	 * So before dismissing a sched group with lesser load,ensure
+ 	 * that the number of processes on it is checked if it is
+ 	 * not too less loaded than the max load so far
+ 	 *
+ 	 * But as of now as LOAD_THRESHOLD is 1,this check is a nop.
+ 	 * But we could vary LOAD_THRESHOLD suitably to bring in this check
+ 	 */
+	if (sgs->avg_cfs_runnable_load <= sds->max_sg_load) {
+		if (sgs->avg_cfs_runnable_load > LOAD_THRESHOLD * sds->max_sg_load) {
+			if (sgs->sum_nr_running <= (NR_THRESHOLD + sds->busiest_nr_running))
+				return false;
+		} else {
+			return false;
+		}
+	}
 
 	if (sgs->sum_nr_running > sgs->group_capacity)
 		return true;
@@ -4708,6 +4726,7 @@ static inline void update_sd_lb_stats(struct lb_env *env,
 			sds->this_idle_cpus = sgs.idle_cpus;
 		} else if (update_sd_pick_busiest(env, sds, sg, &sgs)) {
 			sds->max_load = sgs.avg_load;
+			sds->max_sg_load = sgs.avg_cfs_runnable_load;
 			sds->busiest = sg;
 			sds->busiest_nr_running = sgs.sum_nr_running;
 			sds->busiest_idle_cpus = sgs.idle_cpus;

^ permalink raw reply related

* [RFC PATCH 03/13] sched:Decide whether there be transfer of loads based on the PJT's metric
From: Preeti U Murthy @ 2012-10-25 10:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Additional parameters relevant to sched group load balancing statistics and
sched domain's load balancing statistics which are calculated using the per
entity load tracking are used.

The intention is to begin to use PJT's metric in the first level of load
balancing to see if the current sched group is capable of pulling tasks upon itself.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |   33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index aafa3c1..67a916d 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4157,12 +4157,16 @@ struct sd_lb_stats {
 	struct sched_group *busiest; /* Busiest group in this sd */
 	struct sched_group *this;  /* Local group in this sd */
 	unsigned long total_load;  /* Total load of all groups in sd */
+	u64 total_sgs_load;	 /* Equivalent to total_load except using PJT's metrics */
 	unsigned long total_pwr;   /*	Total power of all groups in sd */
 	unsigned long avg_load;	   /* Average load across all groups in sd */
+	u64 avg_sgs_load;	  /* Equivalent to avg_load but calculated with PJT's metrics */
 
 	/** Statistics of this group */
 	unsigned long this_load;
+	u64 this_sg_load;	/* Equivalent to this_load but calculated using PJT's metric*/
 	unsigned long this_load_per_task;
+	u64 this_sg_load_per_task; /* Equivalent to this_load_per_task but using PJT's metric*/
 	unsigned long this_nr_running;
 	unsigned long this_has_capacity;
 	unsigned int  this_idle_cpus;
@@ -4170,8 +4174,9 @@ struct sd_lb_stats {
 	/* Statistics of the busiest group */
 	unsigned int  busiest_idle_cpus;
 	unsigned long max_load;
-	u64 max_sg_load; /* Equivalent of max_load but calculated using pjt's metric*/
+	u64 max_sg_load; /* Equivalent of max_load but calculated using PJT's metric*/
 	unsigned long busiest_load_per_task;
+	u64 busiest_sg_load_per_task; /*Equivalent of busiest_load_per_task but using PJT's metric*/
 	unsigned long busiest_nr_running;
 	unsigned long busiest_group_capacity;
 	unsigned long busiest_has_capacity;
@@ -4192,6 +4197,7 @@ struct sg_lb_stats {
 	unsigned long avg_load; /*Avg load across the CPUs of the group */
 	u64 avg_cfs_runnable_load; /* Equivalent of avg_load but calculated using PJT's metric */
 	unsigned long group_load; /* Total load over the CPUs of the group */
+	u64 group_cfs_runnable_load; /* Equivalent of group_load but calculated using PJT's metric */
 	unsigned long sum_nr_running; /* Nr tasks running in the group */
 	unsigned long sum_weighted_load; /* Weighted load of group's tasks */
 	unsigned long group_capacity;
@@ -4507,7 +4513,6 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 	unsigned long load, max_cpu_load, min_cpu_load;
 	unsigned int balance_cpu = -1, first_idle_cpu = 0;
 	unsigned long avg_load_per_task = 0;
-	u64 group_load = 0; /* computed using PJT's metric */
 	int i;
 
 	if (local_group)
@@ -4552,7 +4557,8 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 		if (idle_cpu(i))
 			sgs->idle_cpus++;
 
-		group_load += cpu_rq(i)->cfs.runnable_load_avg;
+		/* Tracking load using PJT's metric */
+		sgs->group_cfs_runnable_load += cpu_rq(i)->cfs.runnable_load_avg;
 		update_sg_numa_stats(sgs, rq);
 	}
 
@@ -4585,8 +4591,8 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 	 *
 	 * The below condition is included as a tunable to meet performance and power needs
 	 */
-	sgs->avg_cfs_runnable_load = (group_load * SCHED_POWER_SCALE) / group->sgp->power;
-	if (sgs->avg_cfs_runnable_load <= 1178 && sgs->sum_nr_running <= 2)
+	sgs->avg_cfs_runnable_load = (sgs->group_cfs_runnable_load * SCHED_POWER_SCALE) / group->sgp->power;
+	if (sgs->avg_cfs_runnable_load <= 1178 && sgs->sum_nr_running <= 2 && !local_group)
 		sgs->avg_cfs_runnable_load = 0;
 
 	/*
@@ -4702,6 +4708,8 @@ static inline void update_sd_lb_stats(struct lb_env *env,
 			return;
 
 		sds->total_load += sgs.group_load;
+		/* Tracking load using PJT's metrics */
+		sds->total_sgs_load += sgs.group_cfs_runnable_load;
 		sds->total_pwr += sg->sgp->power;
 
 		/*
@@ -4719,9 +4727,11 @@ static inline void update_sd_lb_stats(struct lb_env *env,
 
 		if (local_group) {
 			sds->this_load = sgs.avg_load;
+			sds->this_sg_load = sgs.avg_cfs_runnable_load;
 			sds->this = sg;
 			sds->this_nr_running = sgs.sum_nr_running;
 			sds->this_load_per_task = sgs.sum_weighted_load;
+			sds->this_sg_load_per_task = sgs.group_cfs_runnable_load;
 			sds->this_has_capacity = sgs.group_has_capacity;
 			sds->this_idle_cpus = sgs.idle_cpus;
 		} else if (update_sd_pick_busiest(env, sds, sg, &sgs)) {
@@ -4732,6 +4742,7 @@ static inline void update_sd_lb_stats(struct lb_env *env,
 			sds->busiest_idle_cpus = sgs.idle_cpus;
 			sds->busiest_group_capacity = sgs.group_capacity;
 			sds->busiest_load_per_task = sgs.sum_weighted_load;
+			sds->busiest_sg_load_per_task = sgs.group_cfs_runnable_load;
 			sds->busiest_has_capacity = sgs.group_has_capacity;
 			sds->busiest_group_weight = sgs.group_weight;
 			sds->group_imb = sgs.group_imb;
@@ -4972,6 +4983,7 @@ find_busiest_group(struct lb_env *env, int *balance)
 		goto out_balanced;
 
 	sds.avg_load = (SCHED_POWER_SCALE * sds.total_load) / sds.total_pwr;
+	sds.avg_sgs_load = (SCHED_POWER_SCALE * sds.total_sgs_load) / sds.total_pwr;
 
 	/*
 	 * If the busiest group is imbalanced the below checks don't
@@ -4990,14 +5002,16 @@ find_busiest_group(struct lb_env *env, int *balance)
 	 * If the local group is more busy than the selected busiest group
 	 * don't try and pull any tasks.
 	 */
-	if (sds.this_load >= sds.max_load)
+	/* The following metrics has been changed to test PJT's metric */
+	if (sds.this_sg_load >= sds.max_sg_load)
 		goto out_balanced;
 
 	/*
 	 * Don't pull any tasks if this group is already above the domain
 	 * average load.
 	 */
-	if (sds.this_load >= sds.avg_load)
+	/* The following metrics has been changed to test PJT's metric */
+	if (sds.this_sg_load >= sds.avg_sgs_load)
 		goto out_balanced;
 
 	if (env->idle == CPU_IDLE) {
@@ -5015,7 +5029,10 @@ find_busiest_group(struct lb_env *env, int *balance)
 		 * In the CPU_NEWLY_IDLE, CPU_NOT_IDLE cases, use
 		 * imbalance_pct to be conservative.
 		 */
-		if (100 * sds.max_load <= env->sd->imbalance_pct * sds.this_load)
+		/* The following metrics has been changed to test PJT's
+		 * metric
+		 */
+		if (100 * sds.max_sg_load <= env->sd->imbalance_pct * sds.this_sg_load)
 			goto out_balanced;
 	}
 

^ permalink raw reply related

* [RFC PATCH 04/13] sched:Decide group_imb using PJT's metric
From: Preeti U Murthy @ 2012-10-25 10:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Additional parameters for deciding a sched group's imbalance status
which are calculated using the per entity load tracking are used.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |   22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 67a916d..77363c6 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3748,6 +3748,7 @@ struct lb_env {
 	int			new_dst_cpu;
 	enum cpu_idle_type	idle;
 	long			imbalance;
+	long long               load_imbalance; /* PJT metric equivalent of imbalance */
 	/* The set of CPUs under consideration for load-balancing */
 	struct cpumask		*cpus;
 
@@ -4513,6 +4514,11 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 	unsigned long load, max_cpu_load, min_cpu_load;
 	unsigned int balance_cpu = -1, first_idle_cpu = 0;
 	unsigned long avg_load_per_task = 0;
+
+	/* Decide imb based on PJT's metric */
+	u64 cpu_runnable_load, max_cpu_runnable_load, min_cpu_runnable_load;
+	u64 avg_sg_load_per_task = 0;
+
 	int i;
 
 	if (local_group)
@@ -4521,6 +4527,8 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 	/* Tally up the load of all CPUs in the group */
 	max_cpu_load = 0;
 	min_cpu_load = ~0UL;
+	max_cpu_runnable_load = 0;
+	min_cpu_runnable_load = ~0ULL;
 	max_nr_running = 0;
 	min_nr_running = ~0UL;
 
@@ -4545,6 +4553,12 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 			if (min_cpu_load > load)
 				min_cpu_load = load;
 
+			cpu_runnable_load = cpu_rq(i)->cfs.runnable_load_avg;
+			if (cpu_runnable_load > max_cpu_runnable_load)
+				max_cpu_runnable_load = cpu_runnable_load;
+			if (min_cpu_runnable_load > cpu_runnable_load)
+				min_cpu_runnable_load = cpu_runnable_load;
+
 			if (nr_running > max_nr_running)
 				max_nr_running = nr_running;
 			if (min_nr_running > nr_running)
@@ -4604,10 +4618,13 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 	 *      normalized nr_running number somewhere that negates
 	 *      the hierarchy?
 	 */
-	if (sgs->sum_nr_running)
+	if (sgs->sum_nr_running) {
 		avg_load_per_task = sgs->sum_weighted_load / sgs->sum_nr_running;
+		avg_sg_load_per_task = sgs->group_cfs_runnable_load / sgs->sum_nr_running;
+	}
 
-	if ((max_cpu_load - min_cpu_load) >= avg_load_per_task &&
+	/* The following decision is made on PJT's metric */
+	if ((max_cpu_runnable_load - min_cpu_runnable_load) >= avg_sg_load_per_task &&
 	    (max_nr_running - min_nr_running) > 1)
 		sgs->group_imb = 1;
 
@@ -5047,6 +5064,7 @@ out_balanced:
 
 ret:
 	env->imbalance = 0;
+	env->load_imbalance = 0;
 	return NULL;
 }
 

^ permalink raw reply related

* [RFC PATCH 05/13] sched:Calculate imbalance using PJT's metric
From: Preeti U Murthy @ 2012-10-25 10:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Additional parameters which decide the amount of imbalance in the sched domain
calculated using PJT's metric are used.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |   36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 77363c6..fca6606 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4892,12 +4892,14 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds)
  */
 static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *sds)
 {
-	unsigned long max_pull, load_above_capacity = ~0UL;
+	/* Additional parameters introduced to use PJT's metric */
+	u64 max_load_pull, load_above_busiest_capacity = ~0ULL;
 
-	sds->busiest_load_per_task /= sds->busiest_nr_running;
+	/* Calculation using PJT's metric */
+	sds->busiest_sg_load_per_task /= sds->busiest_nr_running;
 	if (sds->group_imb) {
-		sds->busiest_load_per_task =
-			min(sds->busiest_load_per_task, sds->avg_load);
+		sds->busiest_sg_load_per_task =
+			min(sds->busiest_sg_load_per_task, sds->avg_sgs_load);
 	}
 
 	/*
@@ -4905,21 +4907,24 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s
 	 * max load less than avg load(as we skip the groups at or below
 	 * its cpu_power, while calculating max_load..)
 	 */
-	if (sds->max_load < sds->avg_load) {
+	if (sds->max_sg_load < sds->avg_sgs_load) {
 		env->imbalance = 0;
+		env->load_imbalance = 0;
 		return fix_small_imbalance(env, sds);
 	}
 
 	if (!sds->group_imb) {
 		/*
 		 * Don't want to pull so many tasks that a group would go idle.
+		 * Also the below change due to the integration with PJT's
+		 * metric
 		 */
-		load_above_capacity = (sds->busiest_nr_running -
+		load_above_busiest_capacity = (sds->busiest_nr_running -
 						sds->busiest_group_capacity);
 
-		load_above_capacity *= (SCHED_LOAD_SCALE * SCHED_POWER_SCALE);
+		load_above_busiest_capacity *= (SCHED_LOAD_SCALE * SCHED_POWER_SCALE);
 
-		load_above_capacity /= sds->busiest->sgp->power;
+		load_above_busiest_capacity /= sds->busiest->sgp->power;
 	}
 
 	/*
@@ -4932,11 +4937,16 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s
 	 * Be careful of negative numbers as they'll appear as very large values
 	 * with unsigned longs.
 	 */
-	max_pull = min(sds->max_load - sds->avg_load, load_above_capacity);
+	/*
+	 * The below maximum load to be pulled is based on the PJT's metric
+ 	 */
+	max_load_pull = min(sds->max_sg_load - sds->avg_sgs_load, load_above_busiest_capacity);
 
-	/* How much load to actually move to equalise the imbalance */
-	env->imbalance = min(max_pull * sds->busiest->sgp->power,
-		(sds->avg_load - sds->this_load) * sds->this->sgp->power)
+	/* How much load to actually move to equalise the imbalance
+ 	 * Calculated using PJT's metric
+	 */
+	env->load_imbalance = min(max_load_pull * sds->busiest->sgp->power,
+		(sds->avg_sgs_load - sds->this_sg_load) * sds->this->sgp->power)
 			/ SCHED_POWER_SCALE;
 
 	/*
@@ -4945,7 +4955,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s
 	 * a think about bumping its value to force at least one task to be
 	 * moved
 	 */
-	if (env->imbalance < sds->busiest_load_per_task)
+	if (env->load_imbalance < sds->busiest_sg_load_per_task)
 		return fix_small_imbalance(env, sds);
 
 }

^ permalink raw reply related

* [RFC PATCH 06/13] sched: Changing find_busiest_queue to use PJT's metric
From: Preeti U Murthy @ 2012-10-25 10:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Additional parameters which decide the busiest cpu in the chosen sched group
calculated using PJT's metric are used

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index fca6606..bb1c71b 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5085,7 +5085,7 @@ static struct rq *find_busiest_queue(struct lb_env *env,
 				     struct sched_group *group)
 {
 	struct rq *busiest = NULL, *rq;
-	unsigned long max_load = 0;
+	u64 max_cpu_load = 0;
 	int i;
 
 	for_each_cpu(i, sched_group_cpus(group)) {
@@ -5093,6 +5093,7 @@ static struct rq *find_busiest_queue(struct lb_env *env,
 		unsigned long capacity = DIV_ROUND_CLOSEST(power,
 							   SCHED_POWER_SCALE);
 		unsigned long wl;
+		u64 runnable_load;/* Equivalent of wl,calculated using PJT's metric */
 
 		if (!capacity)
 			capacity = fix_small_capacity(env->sd, group);
@@ -5102,12 +5103,14 @@ static struct rq *find_busiest_queue(struct lb_env *env,
 
 		rq = cpu_rq(i);
 		wl = weighted_cpuload(i);
+		runnable_load = cpu_rq(i)->cfs.runnable_load_avg;
 
 		/*
 		 * When comparing with imbalance, use weighted_cpuload()
 		 * which is not scaled with the cpu power.
+		 * The below decision is based on PJT's metric
 		 */
-		if (capacity && rq->nr_running == 1 && wl > env->imbalance)
+		if (capacity && rq->nr_running == 1 && runnable_load > env->load_imbalance)
 			continue;
 
 		/*
@@ -5117,9 +5120,11 @@ static struct rq *find_busiest_queue(struct lb_env *env,
 		 * running at a lower capacity.
 		 */
 		wl = (wl * SCHED_POWER_SCALE) / power;
+		runnable_load = (runnable_load * SCHED_POWER_SCALE) / power;
 
-		if (wl > max_load) {
-			max_load = wl;
+		/* Below decision has been changed to use PJT's metric */
+		if (runnable_load > max_cpu_load) {
+			max_cpu_load = runnable_load;
 			busiest = rq;
 		}
 	}

^ permalink raw reply related

* [RFC PATCH 07/13] sched: Change move_tasks to use PJT's metric
From: Preeti U Murthy @ 2012-10-25 10:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Make decisions based on PJT's metrics and the dependent metrics
about which tasks to move to reduce the imbalance.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |   14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index bb1c71b..bd7b69d 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3957,7 +3957,7 @@ static int move_tasks(struct lb_env *env)
 	unsigned long load;
 	int pulled = 0;
 
-	if (env->imbalance <= 0)
+	if (env->load_imbalance <= 0)
 		return 0;
 
 again:
@@ -3984,7 +3984,8 @@ again:
 		if (sched_feat(LB_MIN) && load < 16 && !env->sd->nr_balance_failed)
 			goto next;
 
-		if ((load / 2) > env->imbalance)
+		/* The below being changed to use the PJT's metric */
+		if ((load / 2) > env->load_imbalance)
 			goto next;
 
 		if (!can_migrate_task(p, env))
@@ -3992,7 +3993,8 @@ again:
 
 		move_task(p, env);
 		pulled++;
-		env->imbalance -= load;
+		/* Using PJT's metric */
+		env->load_imbalance -= load;
 
 #ifdef CONFIG_PREEMPT
 		/*
@@ -4007,8 +4009,9 @@ again:
 		/*
 		 * We only want to steal up to the prescribed amount of
 		 * weighted load.
+		 * But the below modification is to use PJT's metric
 		 */
-		if (env->imbalance <= 0)
+		if (env->load_imbalance <= 0)
 			goto out;
 
 		continue;
@@ -4145,7 +4148,8 @@ static inline void update_h_load(long cpu)
 
 static unsigned long task_h_load(struct task_struct *p)
 {
-	return p->se.load.weight;
+	/* The below is changed to use PJT's metric*/
+	return p->se.avg.load_avg_contrib;
 }
 #endif
 

^ permalink raw reply related

* [RFC PATCH 08/13] sched: Some miscallaneous changes in load_balance
From: Preeti U Murthy @ 2012-10-25 10:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Modify certain decisions in load_balance to use the imbalance
amount as calculated by the PJT's metric.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index bd7b69d..68a6b1d 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5284,7 +5284,10 @@ more_balance:
 		 * moreover subsequent load balance cycles should correct the
 		 * excess load moved.
 		 */
-		if ((env.flags & LBF_SOME_PINNED) && env.imbalance > 0 &&
+		/*
+		 * The following decision based on PJT's metric
+ 		 */
+		if ((env.flags & LBF_SOME_PINNED) && env.load_imbalance > 0 &&
 				lb_iterations++ < max_lb_iterations) {
 
 			env.dst_rq	 = cpu_rq(env.new_dst_cpu);

^ permalink raw reply related

* [RFC PATCH 09/13] sched: Modify check_asym_packing to use PJT's metric
From: Preeti U Murthy @ 2012-10-25 10:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Make appropriate modifications in check_asym_packing to reflect PJT's
metric.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 68a6b1d..3b18f5f 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4814,6 +4814,8 @@ static int check_asym_packing(struct lb_env *env, struct sd_lb_stats *sds)
 
 	env->imbalance = DIV_ROUND_CLOSEST(
 		sds->max_load * sds->busiest->sgp->power, SCHED_POWER_SCALE);
+	env->load_imbalance = DIV_ROUND_CLOSEST(
+		sds->max_sg_load * sds->busiest->sgp->power, SCHED_POWER_SCALE);
 
 	return 1;
 }

^ permalink raw reply related

* [RFC PATCH 10/13] sched: Modify fix_small_imbalance to use PJT's metric
From: Preeti U Murthy @ 2012-10-25 10:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Additional parameters which aid in taking the decisions in
fix_small_imbalance which are calculated using PJT's metric are used.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |   54 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 33 insertions(+), 21 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 3b18f5f..a5affbc 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2936,8 +2936,9 @@ static unsigned long cpu_avg_load_per_task(int cpu)
 	struct rq *rq = cpu_rq(cpu);
 	unsigned long nr_running = ACCESS_ONCE(rq->nr_running);
 
-	if (nr_running)
+	if (nr_running) {
 		return rq->load.weight / nr_running;
+	}
 
 	return 0;
 }
@@ -4830,27 +4831,38 @@ static int check_asym_packing(struct lb_env *env, struct sd_lb_stats *sds)
 static inline
 void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds)
 {
-	unsigned long tmp, pwr_now = 0, pwr_move = 0;
+	/* Parameters introduced to use PJT's metrics */
+	u64 tmp, pwr_now = 0, pwr_move = 0;
 	unsigned int imbn = 2;
 	unsigned long scaled_busy_load_per_task;
+	u64 scaled_busy_sg_load_per_task; /* Parameter to use PJT's metric */
+	unsigned long nr_running = ACCESS_ONCE(cpu_rq(env->dst_cpu)->nr_running);
 
 	if (sds->this_nr_running) {
-		sds->this_load_per_task /= sds->this_nr_running;
-		if (sds->busiest_load_per_task >
-				sds->this_load_per_task)
+		sds->this_sg_load_per_task /= sds->this_nr_running;
+		if (sds->busiest_sg_load_per_task >
+				sds->this_sg_load_per_task)
 			imbn = 1;
 	} else {
-		sds->this_load_per_task =
-			cpu_avg_load_per_task(env->dst_cpu);
+		if (nr_running) {
+			sds->this_sg_load_per_task =
+			/* The below decision based on PJT's metric */
+			cpu_rq(env->dst_cpu)->cfs.runnable_load_avg / nr_running;
+		} else {
+			sds->this_sg_load_per_task = 0;
+		}
 	}
 
 	scaled_busy_load_per_task = sds->busiest_load_per_task
 					 * SCHED_POWER_SCALE;
+	scaled_busy_sg_load_per_task = sds->busiest_sg_load_per_task
+					 * SCHED_POWER_SCALE;
 	scaled_busy_load_per_task /= sds->busiest->sgp->power;
+	scaled_busy_sg_load_per_task /= sds->busiest->sgp->power;
 
-	if (sds->max_load - sds->this_load + scaled_busy_load_per_task >=
-			(scaled_busy_load_per_task * imbn)) {
-		env->imbalance = sds->busiest_load_per_task;
+	if (sds->max_sg_load - sds->this_sg_load + scaled_busy_sg_load_per_task >=
+			(scaled_busy_sg_load_per_task * imbn)) {
+		env->load_imbalance = sds->busiest_sg_load_per_task;
 		return;
 	}
 
@@ -4861,33 +4873,33 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds)
 	 */
 
 	pwr_now += sds->busiest->sgp->power *
-			min(sds->busiest_load_per_task, sds->max_load);
+			min(sds->busiest_sg_load_per_task, sds->max_sg_load);
 	pwr_now += sds->this->sgp->power *
-			min(sds->this_load_per_task, sds->this_load);
+			min(sds->this_sg_load_per_task, sds->this_sg_load);
 	pwr_now /= SCHED_POWER_SCALE;
 
 	/* Amount of load we'd subtract */
-	tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) /
+	tmp = (sds->busiest_sg_load_per_task * SCHED_POWER_SCALE) /
 		sds->busiest->sgp->power;
-	if (sds->max_load > tmp)
+	if (sds->max_sg_load > tmp)
 		pwr_move += sds->busiest->sgp->power *
-			min(sds->busiest_load_per_task, sds->max_load - tmp);
+			min(sds->busiest_sg_load_per_task, sds->max_sg_load - tmp);
 
 	/* Amount of load we'd add */
-	if (sds->max_load * sds->busiest->sgp->power <
-		sds->busiest_load_per_task * SCHED_POWER_SCALE)
-		tmp = (sds->max_load * sds->busiest->sgp->power) /
+	if (sds->max_sg_load * sds->busiest->sgp->power <
+		sds->busiest_sg_load_per_task * SCHED_POWER_SCALE)
+		tmp = (sds->max_sg_load * sds->busiest->sgp->power) /
 			sds->this->sgp->power;
 	else
-		tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) /
+		tmp = (sds->busiest_sg_load_per_task * SCHED_POWER_SCALE) /
 			sds->this->sgp->power;
 	pwr_move += sds->this->sgp->power *
-			min(sds->this_load_per_task, sds->this_load + tmp);
+			min(sds->this_sg_load_per_task, sds->this_sg_load + tmp);
 	pwr_move /= SCHED_POWER_SCALE;
 
 	/* Move if we gain throughput */
 	if (pwr_move > pwr_now)
-		env->imbalance = sds->busiest_load_per_task;
+		env->load_imbalance = sds->busiest_sg_load_per_task;
 }
 
 /**

^ permalink raw reply related

* [RFC PATCH 11/13] sched: Modify find_idlest_group to use PJT's metric
From: Preeti U Murthy @ 2012-10-25 10:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Additional parameters introduced to perform this function which are
calculated using PJT's metrics and its helpers.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index a5affbc..c64be1c1 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3173,11 +3173,13 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p,
 		  int this_cpu, int load_idx)
 {
 	struct sched_group *idlest = NULL, *group = sd->groups;
-	unsigned long min_load = ULONG_MAX, this_load = 0;
+	unsigned long this_load = 0;
+	u64 min_sg_load = ~0ULL, this_sg_load = 0;/* Helpers for PJT's metrics */
 	int imbalance = 100 + (sd->imbalance_pct-100)/2;
 
 	do {
 		unsigned long load, avg_load;
+		u64 avg_sg_load;/* Helpers for PJT's metrics */
 		int local_group;
 		int i;
 
@@ -3191,6 +3193,7 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p,
 
 		/* Tally up the load of all CPUs in the group */
 		avg_load = 0;
+		avg_sg_load = 0;
 
 		for_each_cpu(i, sched_group_cpus(group)) {
 			/* Bias balancing toward cpus of our domain */
@@ -3200,20 +3203,23 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p,
 				load = target_load(i, load_idx);
 
 			avg_load += load;
+			avg_sg_load += cpu_rq(i)->cfs.runnable_load_avg;
 		}
 
 		/* Adjust by relative CPU power of the group */
 		avg_load = (avg_load * SCHED_POWER_SCALE) / group->sgp->power;
+		avg_sg_load = (avg_sg_load * SCHED_POWER_SCALE) / group->sgp->power;
 
 		if (local_group) {
 			this_load = avg_load;
-		} else if (avg_load < min_load) {
-			min_load = avg_load;
+			this_sg_load = avg_sg_load;
+		} else if (avg_sg_load < min_sg_load) {/* Decision changed to suit PJT's metric */
+			min_sg_load = avg_sg_load;
 			idlest = group;
 		}
 	} while (group = group->next, group != sd->groups);
 
-	if (!idlest || 100*this_load < imbalance*min_load)
+	if (!idlest || 100*this_sg_load < imbalance*min_sg_load)
 		return NULL;
 	return idlest;
 }

^ permalink raw reply related

* [RFC PATCH 12/13] sched: Modify find_idlest_cpu to use PJT's metric
From: Preeti U Murthy @ 2012-10-25 10:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Additional parameters introduced to perform this function which are
calculated using PJT's metrics and its helpers.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index c64be1c1..15ec528 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3230,16 +3230,18 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p,
 static int
 find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
 {
-	unsigned long load, min_load = ULONG_MAX;
+	unsigned long load;
+	u64 cpu_load, min_cpu_load = ~0ULL;
 	int idlest = -1;
 	int i;
 
 	/* Traverse only the allowed CPUs */
 	for_each_cpu_and(i, sched_group_cpus(group), tsk_cpus_allowed(p)) {
 		load = weighted_cpuload(i);
+		cpu_load = cpu_rq(i)->cfs.runnable_load_avg;
 
-		if (load < min_load || (load == min_load && i == this_cpu)) {
-			min_load = load;
+		if (cpu_load < min_cpu_load || (cpu_load == min_cpu_load && i == this_cpu)) {
+			min_cpu_load = cpu_load;
 			idlest = i;
 		}
 	}

^ permalink raw reply related

* [RFC PATCH 13/13] sched: Modifying wake_affine to use PJT's metric
From: Preeti U Murthy @ 2012-10-25 10:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

Additional parameters introduced to perform this function which are
calculated using PJT's metrics and its helpers.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 kernel/sched/fair.c |   34 +++++++++++++++-------------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 15ec528..b4b572c 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2931,19 +2931,6 @@ static unsigned long power_of(int cpu)
 	return cpu_rq(cpu)->cpu_power;
 }
 
-static unsigned long cpu_avg_load_per_task(int cpu)
-{
-	struct rq *rq = cpu_rq(cpu);
-	unsigned long nr_running = ACCESS_ONCE(rq->nr_running);
-
-	if (nr_running) {
-		return rq->load.weight / nr_running;
-	}
-
-	return 0;
-}
-
-
 static void task_waking_fair(struct task_struct *p)
 {
 	struct sched_entity *se = &p->se;
@@ -3085,16 +3072,18 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
 {
 	s64 this_load, load;
 	int idx, this_cpu, prev_cpu;
-	unsigned long tl_per_task;
+	u64 tl_per_task; /* Modified to reflect PJT's metric */
 	struct task_group *tg;
-	unsigned long weight;
+	unsigned long weight, nr_running;
 	int balanced;
 
 	idx	  = sd->wake_idx;
 	this_cpu  = smp_processor_id();
 	prev_cpu  = task_cpu(p);
-	load	  = source_load(prev_cpu, idx);
-	this_load = target_load(this_cpu, idx);
+	/* Both of the below have been modified to use PJT's metric */
+	load      = cpu_rq(prev_cpu)->cfs.runnable_load_avg;
+	this_load = cpu_rq(this_cpu)->cfs.runnable_load_avg;
+	nr_running = cpu_rq(this_cpu)->nr_running;
 
 	/*
 	 * If sync wakeup then subtract the (maximum possible)
@@ -3104,6 +3093,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
 	if (sync) {
 		tg = task_group(current);
 		weight = current->se.load.weight;
+		weight = current->se.avg.load_avg_contrib;
 
 		this_load += effective_load(tg, this_cpu, -weight, -weight);
 		load += effective_load(tg, prev_cpu, 0, -weight);
@@ -3111,6 +3101,8 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
 
 	tg = task_group(p);
 	weight = p->se.load.weight;
+	/* The below change to reflect PJT's metric */
+	weight = p->se.avg.load_avg_contrib;
 
 	/*
 	 * In low-load situations, where prev_cpu is idle and this_cpu is idle
@@ -3146,11 +3138,15 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
 		return 1;
 
 	schedstat_inc(p, se.statistics.nr_wakeups_affine_attempts);
-	tl_per_task = cpu_avg_load_per_task(this_cpu);
+	/* Below modification to use PJT's metric */
+	if (nr_running)
+		tl_per_task = cpu_rq(this_cpu)->cfs.runnable_load_avg / nr_running;
+	else
+		tl_per_task = 0;
 
 	if (balanced ||
 	    (this_load <= load &&
-	     this_load + target_load(prev_cpu, idx) <= tl_per_task)) {
+	     this_load + cpu_rq(prev_cpu)->cfs.runnable_load_avg <= tl_per_task)) {
 		/*
 		 * This domain has SD_WAKE_AFFINE and
 		 * p is cache cold in this domain, and

^ permalink raw reply related

* [PATCH] [RFC] pinctrl: mvebu: reset pins to an UNKNOWN state on startup
From: Mark Brown @ 2012-10-25 10:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdaxUS95vPLsW0kSbPn3g0ywMg+MJhrbEJBRa4uaLvw4Fg@mail.gmail.com>

On Thu, Oct 25, 2012 at 08:46:38AM +0200, Linus Walleij wrote:

> Now I don't know which kernel senior being it was that told me
> never to screw around with the defaults from the boot loader
> if not really needed. It is better if the driver reads the hardware
> to figure out what state it's in and move on from there.

This depends on the platform quite a bit - there's two schools of
thought on what bootloaders should do, and typically platforms decide on
a per platform basis which they'll use:

 1. The bootloader does enough to load the kernel and nothing more, the
    kernel should ignore anything the bootloader did.  Some people
    prefer this as it places minimal reliance on the bootloader which
    may be of uncertain quality and minimises the need to upgrade the
    bootloader which is often highly risky.

 2. The bootloader does all the pin setup and so on.  This provides a
    place for board specific stuff and avoids the kernel having to know
    about lots of device variants.

For example AIUI OMAP tends towards the second view (partly due to
number of device variants) but for example Samsung platforms typically
use the first method (their pinmux is pretty simple).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121025/f30f4e79/attachment-0001.sig>

^ permalink raw reply

* [PATCH 3/8] i2c: omap: fix error checking
From: Michael Trimarchi @ 2012-10-25 10:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025101010.GC21217@arwen.pp.htv.fi>

Hi

On 10/25/2012 12:10 PM, Felipe Balbi wrote:
> Hi,
> 
> On Wed, Oct 24, 2012 at 04:41:11PM +0200, Michael Trimarchi wrote:
>> Hi
>>
>> On 10/22/2012 11:46 AM, Felipe Balbi wrote:
>>> It's impossible to have Arbitration Lost,
>>> Read Overflow, and Tranmist Underflow all
>>> asserted at the same time.
>>>
>>> Those error conditions are mutually exclusive
>>> so what the code should be doing, instead, is
>>> check each error flag separataly.
>>>
>>> Signed-off-by: Felipe Balbi <balbi@ti.com>
>>> ---
>>>  drivers/i2c/busses/i2c-omap.c | 6 +++---
>>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
>>> index bea0277..e0eab38 100644
>>> --- a/drivers/i2c/busses/i2c-omap.c
>>> +++ b/drivers/i2c/busses/i2c-omap.c
>>> @@ -587,9 +587,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
>>>  		goto err_i2c_init;
>>>  	}
>>>  
>>> -	/* We have an error */
>>> -	if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR |
>>> -			    OMAP_I2C_STAT_XUDF)) {
>>> +	if ((dev->cmd_err & OMAP_I2C_STAT_AL)
>>> +			|| (dev->cmd_err & OMAP_I2C_STAT_ROVR)
>>> +			|| (dev->cmd_err & OMAP_I2C_STAT_XUDF)) {
>>
>> Sorry, what is the difference? I didn't understand the optimisation
>> and why now is more clear. Can you just add a comment?
> 
> semantically they're not the same, right ? We want to check if each of
> those bits are set, not if all of them are set together.
> 
> my 2 cents.

You are doing the same thing, but of course is better with just one *if* as before . A general rule is: when you have logic expression you can use undefined states to simplify the logic. 

Michael 

^ permalink raw reply

* [RFC PATCH 00/13] sched: Integrating Per-entity-load-tracking with the core scheduler
From: Preeti Murthy @ 2012-10-25 10:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

The benchmark:
/*
 * test.c - Simulate workloads that load the CPU differently
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 */

/*
 * This workload spawns threads which request for allocation of a
 * memory chunk,write to it and free it.The duty cycle of these threads
 * can be varied.The idea is to simulate tasks which load the cpu
 * to different extents.
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <pthread.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "malloc.h"

/* Variable entities */
static unsigned int seconds;
static unsigned int threads;
static unsigned int mem_chunk_size;
static unsigned int sleep_at;
static unsigned int sleep_interval;

typedef size_t mem_slot_t;/* 8 bytes */
static unsigned int slot_size = sizeof(mem_slot_t);

/* Other parameters */
static volatile int start;
static time_t start_time;
static unsigned int records_read;
pthread_mutex_t records_count_lock = PTHREAD_MUTEX_INITIALIZER;


static unsigned int write_to_mem(void)
{
    int i, j;
    mem_slot_t *scratch_pad, *temp;
    mem_chunk_size = slot_size * 256;
    mem_slot_t *end;

    /* The below two parameters ensure that it is 10% workload
     * with a duty cycle of 10ms.The number of records read in
     * 1s without sleep was observed and appropriately calculated
     * for 1ms.This number turned out to be 1228.
     */
    sleep_at = 1228; /* sleep for every 1228 records */
    sleep_interval = 9000; /* sleep for 9 ms */

    for (i=0; start == 1; i++)
    {
        scratch_pad = (mem_slot_t *)malloc(mem_chunk_size);
        if (scratch_pad == NULL) {
            fprintf(stderr,"Could not allocate memory\n");
            exit(1);
        }
        end = scratch_pad + (mem_chunk_size / slot_size);
        for (temp = scratch_pad, j=0; temp < end; temp++, j++)
            *temp = (mem_slot_t)j;

        free(scratch_pad);

        if (sleep_at && !(i % sleep_at))
            usleep(sleep_interval);
    }
    return (i);
}

static void *
thread_run(void *arg)
{

    unsigned int records_local;

    /* Wait for the start signal */

    while (start == 0);

    records_local = write_to_mem();

    pthread_mutex_lock(&records_count_lock);
    records_read += records_local;
    pthread_mutex_unlock(&records_count_lock);

    return NULL;
}

static void start_threads()
{
    double diff_time;
    unsigned int i;
    int err;
    threads = 8;
    seconds = 10;

    pthread_t thread_array[threads];
    for (i = 0; i < threads; i++) {
        err = pthread_create(&thread_array[i], NULL, thread_run, NULL);
        if (err) {
            fprintf(stderr, "Error creating thread %d\n", i);
            exit(1);
        }
    }
    start_time = time(NULL);
    start = 1;
    sleep(seconds);
    start = 0;
    diff_time = difftime(time(NULL), start_time);

    for (i = 0; i < threads; i++) {
        err = pthread_join(thread_array[i], NULL);
        if (err) {
            fprintf(stderr, "Error joining thread %d\n", i);
            exit(1);
        }
    }
     printf("%u records/s\n",
        (unsigned int) (((double) records_read)/diff_time));

}
int main()
{
    start_threads();
    return 0;
}


Regards
Preeti U Murthy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121025/9ebd9749/attachment-0001.html>

^ permalink raw reply

* [PATCH 3/8] i2c: omap: fix error checking
From: Felipe Balbi @ 2012-10-25 10:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5089156E.7020701@amarulasolutions.com>

Hi,

On Thu, Oct 25, 2012 at 12:33:18PM +0200, Michael Trimarchi wrote:
> >>> @@ -587,9 +587,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
> >>>  		goto err_i2c_init;
> >>>  	}
> >>>  
> >>> -	/* We have an error */
> >>> -	if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR |
> >>> -			    OMAP_I2C_STAT_XUDF)) {
> >>> +	if ((dev->cmd_err & OMAP_I2C_STAT_AL)
> >>> +			|| (dev->cmd_err & OMAP_I2C_STAT_ROVR)
> >>> +			|| (dev->cmd_err & OMAP_I2C_STAT_XUDF)) {
> >>
> >> Sorry, what is the difference? I didn't understand the optimisation
> >> and why now is more clear. Can you just add a comment?
> > 
> > semantically they're not the same, right ? We want to check if each of
> > those bits are set, not if all of them are set together.
> > 
> > my 2 cents.
> 
> You are doing the same thing, but of course is better with just one

I never claimed the contrary. I said *semantically* they're not the
same.

> *if* as before . A general rule is: when you have logic expression you

We still have a single *if* and I'm sure compiler will optimize that
expression as much as it likes.

> can use undefined states to simplify the logic. 

don't-care is not the same as undefined states.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121025/cbb6ab32/attachment.sig>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox