Re: [PATCH 3/3] serial: 8250: omap: restore registers on shutdown

2015-08-06 Thread Charles Manning
On Fri, Aug 7, 2015 at 6:22 AM, Peter Hurley  wrote:
> I agree; this is what we should do first because someone might want it
> for backports.

Got an idea how far this can be ported back?

I'm being hampered by severe performance issues on a
beagleboneblack-like device (am335x) running on 3.18 kernel.

I have a 1Mbaud link that is getting packets of about 22 bytes @800 Hz
and old omap-serial is keeping up, but killing the CPU.

I'm considering backporting 8250_omap as a get out of jail.

Opinions appreciated.

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] clk : Clean up checkpatch warnings

2014-07-21 Thread Charles Manning
Signed-off-by: Charles Manning 
---
 drivers/clk/clk.c | 33 ++---
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 8b73ede..ec41922 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -99,7 +99,7 @@ static void clk_enable_unlock(unsigned long flags)
 
 static struct dentry *rootdir;
 static struct dentry *orphandir;
-static int inited = 0;
+static int inited;
 
 static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
 {
@@ -182,11 +182,11 @@ static void clk_dump_subtree(struct seq_file *s, struct 
clk *c, int level)
clk_dump_one(s, c, level);
 
hlist_for_each_entry(child, &c->children, child_node) {
-   seq_printf(s, ",");
+   seq_puts(s, ",");
clk_dump_subtree(s, child, level + 1);
}
 
-   seq_printf(s, "}");
+   seq_puts(s, "}");
 }
 
 static int clk_dump(struct seq_file *s, void *data)
@@ -194,25 +194,25 @@ static int clk_dump(struct seq_file *s, void *data)
struct clk *c;
bool first_node = true;
 
-   seq_printf(s, "{");
+   seq_puts(s, "{");
 
clk_prepare_lock();
 
hlist_for_each_entry(c, &clk_root_list, child_node) {
if (!first_node)
-   seq_printf(s, ",");
+   seq_puts(s, ",");
first_node = false;
clk_dump_subtree(s, c, 0);
}
 
hlist_for_each_entry(c, &clk_orphan_list, child_node) {
-   seq_printf(s, ",");
+   seq_puts(s, ",");
clk_dump_subtree(s, c, 0);
}
 
clk_prepare_unlock();
 
-   seq_printf(s, "}");
+   seq_puts(s, "}");
return 0;
 }
 
@@ -294,7 +294,7 @@ out:
 static int clk_debug_create_subtree(struct clk *clk, struct dentry *pdentry)
 {
struct clk *child;
-   int ret = -EINVAL;;
+   int ret = -EINVAL;
 
if (!clk || !pdentry)
goto out;
@@ -1455,7 +1455,8 @@ out:
  * so that in case of an error we can walk down the whole tree again and
  * abort the change.
  */
-static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long 
event)
+static struct clk *clk_propagate_rate_change(struct clk *clk,
+unsigned long event)
 {
struct clk *child, *tmp_clk, *fail_clk = NULL;
int ret = NOTIFY_DONE;
@@ -1798,14 +1799,14 @@ int __clk_init(struct device *dev, struct clk *clk)
if (clk->ops->set_rate &&
!((clk->ops->round_rate || clk->ops->determine_rate) &&
  clk->ops->recalc_rate)) {
-   pr_warning("%s: %s must implement .round_rate or 
.determine_rate in addition to .recalc_rate\n",
+   pr_warn("%s: %s must implement .round_rate or .determine_rate 
in addition to .recalc_rate\n",
__func__, clk->name);
ret = -EINVAL;
goto out;
}
 
if (clk->ops->set_parent && !clk->ops->get_parent) {
-   pr_warning("%s: %s must implement .get_parent & .set_parent\n",
+   pr_warn("%s: %s must implement .get_parent & .set_parent\n",
__func__, clk->name);
ret = -EINVAL;
goto out;
@@ -2116,8 +2117,8 @@ void clk_unregister(struct clk *clk)
 {
unsigned long flags;
 
-   if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
-   return;
+   if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
+   return;
 
clk_prepare_lock();
 
@@ -2194,6 +2195,7 @@ EXPORT_SYMBOL_GPL(devm_clk_register);
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
struct clk *c = res;
+
if (WARN_ON(!c))
return 0;
return c == data;
@@ -2409,8 +2411,9 @@ EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
  * @data: context pointer for @clk_src_get callback.
  */
 int of_clk_add_provider(struct device_node *np,
-   struct clk *(*clk_src_get)(struct of_phandle_args 
*clkspec,
-  void *data),
+   struct clk *(*clk_src_get)
+   (struct of_phandle_args *clkspec,
+void *data),
void *data)
 {
struct of_clk_provider *cp;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] clk: Prevent a hanging pointer being abused

2014-07-21 Thread Charles Manning
Clock init structs are normally created on the stack.

If the pointer is left intact after clk_register then there is
opportunity for clk drivers to dereference the pointer.

This was causing a problem in socfpga/clk.c for instance.

Better to NULL out the pointer so it can't be abused.

Signed-off-by: Charles Manning 
---
 drivers/clk/clk.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index ec41922..9e92170 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1973,6 +1973,10 @@ struct clk *__clk_register(struct device *dev, struct 
clk_hw *hw)
clk->owner = NULL;
 
ret = __clk_init(dev, clk);
+
+   /* Prevent a hanging pointer being left around. */
+   hw->init = NULL;
+
if (ret)
return ERR_PTR(ret);
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] clk: socfpga Change name look-up to not use the init pointer

2014-07-21 Thread Charles Manning
The init pointer is not valid after clk_register so we store
the names with the socfpga clock structures so we can look them up.

Signed-off-by: Charles Manning 
---
 drivers/clk/socfpga/clk-gate.c   | 44 ++--
 drivers/clk/socfpga/clk-periph.c | 16 ++-
 drivers/clk/socfpga/clk-pll.c| 13 
 drivers/clk/socfpga/clk.h|  7 ---
 4 files changed, 53 insertions(+), 27 deletions(-)

diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
index dd3a78c..a319f01 100644
--- a/drivers/clk/socfpga/clk-gate.c
+++ b/drivers/clk/socfpga/clk-gate.c
@@ -34,7 +34,10 @@
 
 #define streq(a, b) (strcmp((a), (b)) == 0)
 
-#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw)
+#define to_socfpga_gate_clk(p) \
+   container_of(p, struct socfpga_gate_clk, base.hw.hw)
+#define to_socfpga_base_clk(p) \
+   container_of(p, struct socfpga_base_clk, hw.hw)
 
 /* SDMMC Group for System Manager defines */
 #define SYSMGR_SDMMCGRP_CTRL_OFFSET0x108
@@ -45,21 +48,24 @@ static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
 {
u32 l4_src;
u32 perpll_src;
+   struct socfpga_base_clk *base_clk;
 
-   if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
+   base_clk = to_socfpga_base_clk(hwclk);
+
+   if (streq(base_clk->name, SOCFPGA_L4_MP_CLK)) {
l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
return l4_src &= 0x1;
}
-   if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
+   if (streq(base_clk->name, SOCFPGA_L4_SP_CLK)) {
l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
return !!(l4_src & 2);
}
 
perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
-   if (streq(hwclk->init->name, SOCFPGA_MMC_CLK))
+   if (streq(base_clk->name, SOCFPGA_MMC_CLK))
return perpll_src &= 0x3;
-   if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
-   streq(hwclk->init->name, SOCFPGA_NAND_X_CLK))
+   if (streq(base_clk->name, SOCFPGA_NAND_CLK) ||
+   streq(base_clk->name, SOCFPGA_NAND_X_CLK))
return (perpll_src >> 2) & 3;
 
/* QSPI clock */
@@ -70,24 +76,27 @@ static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
 static int socfpga_clk_set_parent(struct clk_hw *hwclk, u8 parent)
 {
u32 src_reg;
+   struct socfpga_base_clk *base_clk;
+
+   base_clk = to_socfpga_base_clk(hwclk);
 
-   if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
+   if (streq(base_clk->name, SOCFPGA_L4_MP_CLK)) {
src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
src_reg &= ~0x1;
src_reg |= parent;
writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
-   } else if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
+   } else if (streq(base_clk->name, SOCFPGA_L4_SP_CLK)) {
src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
src_reg &= ~0x2;
src_reg |= (parent << 1);
writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
} else {
src_reg = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
-   if (streq(hwclk->init->name, SOCFPGA_MMC_CLK)) {
+   if (streq(base_clk->name, SOCFPGA_MMC_CLK)) {
src_reg &= ~0x3;
src_reg |= parent;
-   } else if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
-   streq(hwclk->init->name, SOCFPGA_NAND_X_CLK)) {
+   } else if (streq(base_clk->name, SOCFPGA_NAND_CLK) ||
+   streq(base_clk->name, SOCFPGA_NAND_X_CLK)) {
src_reg &= ~0xC;
src_reg |= (parent << 2);
} else {/* QSPI clock */
@@ -205,8 +214,8 @@ static void __init __socfpga_gate_init(struct device_node 
*node,
clk_gate[0] = 0;
 
if (clk_gate[0]) {
-   socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
-   socfpga_clk->hw.bit_idx = clk_gate[1];
+   socfpga_clk->base.hw.reg = clk_mgr_base_addr + clk_gate[0];
+   socfpga_clk->base.hw.bit_idx = clk_gate[1];
 
gateclk_ops.enable = clk_gate_ops.enable;
gateclk_ops.disable = clk_gate_ops.disable;
@@ -244,9 +253,14 @@ static void __init __socfpga_gate_init(struct device_node 
*node,
 
init.parent_names = parent_name;
init.num_parents = i;
-   socfpga_clk->hw.hw.init = &init;
+   socfpga_clk->base.hw.hw.init = &init;
+   socfpga_clk->base.name = kstrdup(clk_name, GFP_KERNEL);
+   if (WARN_ON(!socfpga_clk->base.name)) {

[PATCH 0/3] clk : Fix SOCFPGA clk crash and some clean up

2014-07-21 Thread Charles Manning
After some digging into a crash on the SOCFPGA initialisation it was
determined that this was due to the SOCFPGA's name look-up dereferencing
the clock init pointer. This is a bad thing to do because the init data is
constructed on the stack and thus a pointer to the init data is no longer
valid after clk_register() has been called.

Most, if not all, drivers create the init data on the stack. Thus init 
pointer should not be left hanging after it has been used in clk_register.
Thus one of these patches NULLs the pointer so it can't be abused.

In the long term, it would be way, way better to pass the init pointer as
an argument rather than as a pointer in hw.


Charles Manning (3):
  clk : Clean up checkpatch warnings
  clk: Prevent a hanging pointer being abused
  clk: socfpga Change name look-up to not use the init pointer

 drivers/clk/clk.c| 37 +++--
 drivers/clk/socfpga/clk-gate.c   | 44 ++--
 drivers/clk/socfpga/clk-periph.c | 16 ++-
 drivers/clk/socfpga/clk-pll.c| 13 
 drivers/clk/socfpga/clk.h|  7 ---
 5 files changed, 75 insertions(+), 42 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [ANNOUNCE] RAIF: Redundant Array of Independent Filesystems

2006-12-14 Thread Charles Manning
On Friday 15 December 2006 10:01, Nikolai Joukov wrote:
> > Nikolai Joukov wrote:
> > > We have designed a new stackable file system that we called RAIF:
> > > Redundant Array of Independent Filesystems.
> >
> > Great!

Yes, definitely...

I see the major benefit being in the mobile, industrial and embedded systems 
arena. Perhaps this might come as a suprise to people, but a very large and 
ever growing number (perhaps even most) Linux devices don't use block devices 
for storage. Instead they use flash file systems or nfs, niether of which use 
local block devices.

It looks like RAIF gives a way to provide redundancy etc on these devices.


> >
> > > We have performed some benchmarking on a 3GHz PC with 2GB of RAM and
> > > U320 SCSI disks.  Compared to the Linux RAID driver, RAIF has overheads
> > > of about 20-25% under the Postmark v1.5 benchmark in case of striping
> > > and replication.  In case of RAID4 and RAID5-like configurations, RAIF
> > > performed about two times *better* than software RAID and even better
> > > than an Adaptec 2120S RAID5 controller.
> >
> > I am not surprised.  RAID 4/5/6 performance is highly sensitive to the
> > underlying hw, and thus needs a fair amount of fine tuning.
>
> Nevertheless, performance is not the biggest advantage of RAIF.  For
> read-biased workloads RAID is always slightly faster than RAIF.  The
> biggest advantages of RAIF are flexible configurations (e.g., can combine
> NFS and local file systems), per-file-type storage policies, and the fact
> that files are stored as files on the lower file systems (which is
> convenient).
>
> > > This is because RAIF is located above
> > > file system caches and can cache parity as normal data when needed.  We
> > > have more performance details in a technical report, if anyone is
> > > interested.
> >
> > Definitely interested.  Can you give a link?
>
> The main focus of the paper is on a general OS profiling method and not
> on RAIF.  However, it has some details about the RAIF benchmarking with
> Postmark in Chapter 9:
>
>   
>
> Figures 9.7 and 9.8 also show profiles of the Linux RAID5 and RAIF5
> operation under the same Postmark workload.
>
> Nikolai.
> -
> Nikolai Joukov, Ph.D.
> Filesystems and Storage Laboratory
> Stony Brook University
> -
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to [EMAIL PROTECTED]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/