All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 13/X] uprobes: introduce UTASK_SSTEP_TRAPPED logic
From: Ananth N Mavinakayanahalli @ 2011-10-24 15:16 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Srikar Dronamraju, Peter Zijlstra, Ingo Molnar, Steven Rostedt,
	Linux-mm, Arnaldo Carvalho de Melo, Linus Torvalds,
	Jonathan Corbet, Masami Hiramatsu, Hugh Dickins,
	Christoph Hellwig, Thomas Gleixner, Andi Kleen, Andrew Morton,
	Jim Keniston, Roland McGrath, LKML
In-Reply-To: <20111024144127.GA14975@redhat.com>

On Mon, Oct 24, 2011 at 04:41:27PM +0200, Oleg Nesterov wrote:
> On 10/22, Ananth N Mavinakayanahalli wrote:
> >
> > On Wed, Oct 19, 2011 at 11:53:44PM +0200, Oleg Nesterov wrote:
> > > Finally, add UTASK_SSTEP_TRAPPED state/code to handle the case when
> > > xol insn itself triggers the signal.
> > >
> > > In this case we should restart the original insn even if the task is
> > > already SIGKILL'ed (say, the coredump should report the correct ip).
> > > This is even more important if the task has a handler for SIGSEGV/etc,
> > > The _same_ instruction should be repeated again after return from the
> > > signal handler, and SSTEP can never finish in this case.
> >
> > Oleg,
> >
> > Not sure I understand this completely...
> 
> I hope you do not think I do ;)

I think you understand it better than you think you do :-)

> > When you say 'correct ip' you mean the original vaddr where we now have
> > a uprobe breakpoint and not the xol copy, right?
> 
> Yes,
> 
> > Coredump needs to report the correct ip, but should it also not report
> > correctly the instruction that caused the signal? Ergo, shouldn't we
> > put the original instruction back at the uprobed vaddr?
> 
> OK, now I see what you mean. I was confused by the "restore the original
> instruction before _restart_" suggestion.
> 
> Agreed! it would be nice to "hide" these int3's if we dump the core, but
> I think this is a bit off-topic. It makes sense to do this in any case,
> even if the core-dumping was triggered by another thread/insn. It makes
> sense to remove all int3's, not only at regs->ip location. But how can
> we do this? This is nontrivial.

I don't think that is a problem.. see below...

> And. Even worse. Suppose that you do "gdb probed_application". Now you
> see int3's in the disassemble output. What can we do?

In this case, nothing.

> I think we can do nothing, at least currently. This just reflects the
> fact that uprobe connects to inode, not to process/mm/etc.
> 
> What do you think?

Thinking further on this, in the normal 'running gdb on a core' case, we
won't have this problem, as the binary that we point gdb to, will be a
pristine one, without the uprobe int3s, right?

Ananth


^ permalink raw reply

* [PATCH 3/3] mfd: Add S5M series configuration
From: Sangbeom Kim @ 2011-10-21 10:28 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie, Sangbeom Kim
In-Reply-To: <1319192894-19292-1-git-send-email-sbkim73@samsung.com>

This patch add S5M series configuration.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 drivers/mfd/Kconfig  |   12 ++++++++++++
 drivers/mfd/Makefile |    1 +
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 21574bd..e280d2a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -386,6 +386,18 @@ config MFD_MAX8998
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 
+config MFD_S5M_CORE
+	bool "SAMSUNG S5M Series Support"
+	depends on I2C=y && GENERIC_HARDIRQS
+	select MFD_CORE
+	select REGMAP_I2C
+	help
+	  Say yes here to support for SAMSUNG S5M series.
+	  This is a Power Management IC.
+	  This driver provies common support for accessing the device,
+	  additional drivers must be enabled in order to use the functionality
+	  of the device
+
 config MFD_WM8400
 	tristate "Support Wolfson Microelectronics WM8400"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c580203..dfd05a2 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -102,3 +102,4 @@ obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o
 obj-$(CONFIG_MFD_PM8XXX_IRQ) 	+= pm8xxx-irq.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o
+obj-$(CONFIG_MFD_S5M_CORE)	+= s5m-core.o s5m-irq.o
-- 
1.7.1


^ permalink raw reply related

* [PATCH 3/3] mfd: Add S5M series configuration
From: Sangbeom Kim @ 2011-10-23  7:30 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie, Sangbeom Kim
In-Reply-To: <1319355002-12674-1-git-send-email-sbkim73@samsung.com>

This patch add S5M series configuration.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 drivers/mfd/Kconfig  |   12 ++++++++++++
 drivers/mfd/Makefile |    1 +
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 21574bd..e280d2a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -386,6 +386,18 @@ config MFD_MAX8998
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 
+config MFD_S5M_CORE
+	bool "SAMSUNG S5M Series Support"
+	depends on I2C=y && GENERIC_HARDIRQS
+	select MFD_CORE
+	select REGMAP_I2C
+	help
+	  Say yes here to support for SAMSUNG S5M series.
+	  This is a Power Management IC.
+	  This driver provies common support for accessing the device,
+	  additional drivers must be enabled in order to use the functionality
+	  of the device
+
 config MFD_WM8400
 	tristate "Support Wolfson Microelectronics WM8400"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c580203..dfd05a2 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -102,3 +102,4 @@ obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o
 obj-$(CONFIG_MFD_PM8XXX_IRQ) 	+= pm8xxx-irq.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o
+obj-$(CONFIG_MFD_S5M_CORE)	+= s5m-core.o s5m-irq.o
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/3] mfd: S5M core driver initial release
From: Sangbeom Kim @ 2011-10-21 10:28 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie

Samsung has released various MFD series.
S5M8767 has pmic and rtc and battery charger.
S5M8763 has pmic, rtc, battery charger.
S5M8751 has pmic, codec, battery charger, backlight controller.
All devices are designed for mobile applications.
Sequencially, All driver will be posted.
This is initial version for MFD of S5M series.
The other driver will be submitted  separately.

Thanks,
Sangbeom.

^ permalink raw reply

* [PATCH 2/3] mfd: Add s5m series irq support
From: Sangbeom Kim @ 2011-10-23  7:30 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie, Sangbeom Kim
In-Reply-To: <1319355002-12674-1-git-send-email-sbkim73@samsung.com>

This patch support irq for s5m series.
Basically, S5M8767 and S5M8763 irq can be handled by this patch.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 drivers/mfd/s5m-irq.c |  486 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 486 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/s5m-irq.c

diff --git a/drivers/mfd/s5m-irq.c b/drivers/mfd/s5m-irq.c
new file mode 100644
index 0000000..6a4a71a
--- /dev/null
+++ b/drivers/mfd/s5m-irq.c
@@ -0,0 +1,486 @@
+/*
+ * s5m-irq.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  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;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+
+struct s5m_irq_data {
+	int reg;
+	int mask;
+};
+
+static struct s5m_irq_data s5m8767_irqs[] = {
+	[S5M8767_IRQ_PWRR] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_PWRR_MASK,
+	},
+	[S5M8767_IRQ_PWRF] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_PWRF_MASK,
+	},
+	[S5M8767_IRQ_PWR1S] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_PWR1S_MASK,
+	},
+	[S5M8767_IRQ_JIGR] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_JIGR_MASK,
+	},
+	[S5M8767_IRQ_JIGF] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_JIGF_MASK,
+	},
+	[S5M8767_IRQ_LOWBAT2] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_LOWBAT2_MASK,
+	},
+	[S5M8767_IRQ_LOWBAT1] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_LOWBAT1_MASK,
+	},
+	[S5M8767_IRQ_MRB] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_MRB_MASK,
+	},
+	[S5M8767_IRQ_DVSOK2] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_DVSOK2_MASK,
+	},
+	[S5M8767_IRQ_DVSOK3] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_DVSOK3_MASK,
+	},
+	[S5M8767_IRQ_DVSOK4] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_DVSOK4_MASK,
+	},
+	[S5M8767_IRQ_RTC60S] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTC60S_MASK,
+	},
+	[S5M8767_IRQ_RTCA1] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTCA1_MASK,
+	},
+	[S5M8767_IRQ_RTCA2] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTCA2_MASK,
+	},
+	[S5M8767_IRQ_SMPL] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_SMPL_MASK,
+	},
+	[S5M8767_IRQ_RTC1S] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTC1S_MASK,
+	},
+	[S5M8767_IRQ_WTSR] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_WTSR_MASK,
+	},
+};
+
+static struct s5m_irq_data s5m8763_irqs[] = {
+	[S5M8763_IRQ_VDCINF] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_VDCINF_MASK,
+	},
+	[S5M8763_IRQ_VDCINR] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_VDCINR_MASK,
+	},
+	[S5M8763_IRQ_JIGF] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_JIGF_MASK,
+	},
+	[S5M8763_IRQ_JIGR] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_JIGR_MASK,
+	},
+	[S5M8763_IRQ_PWRONF] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_PWRONF_MASK,
+	},
+	[S5M8763_IRQ_PWRONR] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_PWRONR_MASK,
+	},
+	[S5M8763_IRQ_WTSREVNT] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_WTSREVNT_MASK,
+	},
+	[S5M8763_IRQ_SMPLEVNT] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_SMPLEVNT_MASK,
+	},
+	[S5M8763_IRQ_ALARM1] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_ALARM1_MASK,
+	},
+	[S5M8763_IRQ_ALARM0] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_ALARM0_MASK,
+	},
+	[S5M8763_IRQ_ONKEY1S] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_ONKEY1S_MASK,
+	},
+	[S5M8763_IRQ_TOPOFFR] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_TOPOFFR_MASK,
+	},
+	[S5M8763_IRQ_VDCINOVPR] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_VDCINOVPR_MASK,
+	},
+	[S5M8763_IRQ_CHGRSTF] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_CHGRSTF_MASK,
+	},
+	[S5M8763_IRQ_DONER] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_DONER_MASK,
+	},
+	[S5M8763_IRQ_CHGFAULT] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_CHGFAULT_MASK,
+	},
+	[S5M8763_IRQ_LOBAT1] = {
+		.reg = 4,
+		.mask = S5M8763_IRQ_LOBAT1_MASK,
+	},
+	[S5M8763_IRQ_LOBAT2] = {
+		.reg = 4,
+		.mask = S5M8763_IRQ_LOBAT2_MASK,
+	},
+};
+
+static inline struct s5m_irq_data *
+irq_to_s5m8767_irq(struct s5m87xx_dev *s5m87xx, int irq)
+{
+	return &s5m8767_irqs[irq - s5m87xx->irq_base];
+}
+
+static void s5m8767_irq_lock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&s5m87xx->irqlock);
+}
+
+static void s5m8767_irq_sync_unlock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) {
+		if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) {
+			s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i];
+			s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i,
+					s5m87xx->irq_masks_cur[i]);
+		}
+	}
+
+	mutex_unlock(&s5m87xx->irqlock);
+}
+
+static void s5m8767_irq_unmask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void s5m8767_irq_mask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip s5m8767_irq_chip = {
+	.name = "s5m8767",
+	.irq_bus_lock = s5m8767_irq_lock,
+	.irq_bus_sync_unlock = s5m8767_irq_sync_unlock,
+	.irq_mask = s5m8767_irq_mask,
+	.irq_unmask = s5m8767_irq_unmask,
+};
+
+static inline struct s5m_irq_data *
+irq_to_s5m8763_irq(struct s5m87xx_dev *s5m87xx, int irq)
+{
+	return &s5m8763_irqs[irq - s5m87xx->irq_base];
+}
+
+static void s5m8763_irq_lock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&s5m87xx->irqlock);
+}
+
+static void s5m8763_irq_sync_unlock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) {
+		if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) {
+			s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i];
+			s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i,
+					s5m87xx->irq_masks_cur[i]);
+		}
+	}
+
+	mutex_unlock(&s5m87xx->irqlock);
+}
+
+static void s5m8763_irq_unmask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void s5m8763_irq_mask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip s5m8763_irq_chip = {
+	.name = "s5m8763",
+	.irq_bus_lock = s5m8763_irq_lock,
+	.irq_bus_sync_unlock = s5m8763_irq_sync_unlock,
+	.irq_mask = s5m8763_irq_mask,
+	.irq_unmask = s5m8763_irq_unmask,
+};
+
+static irqreturn_t s5m8767_irq_thread(int irq, void *data)
+{
+	struct s5m87xx_dev *s5m87xx = data;
+	u8 irq_reg[NUM_IRQ_REGS-1];
+	int ret;
+	int i;
+
+	ret = s5m_bulk_read(s5m87xx, S5M8767_REG_INT1,
+				NUM_IRQ_REGS - 1, irq_reg);
+	if (ret < 0) {
+		dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n",
+				ret);
+		return IRQ_NONE;
+	}
+
+	for (i = 0; i < NUM_IRQ_REGS - 1; i++)
+		irq_reg[i] &= ~s5m87xx->irq_masks_cur[i];
+
+	for (i = 0; i < S5M8767_IRQ_NR; i++) {
+		if (irq_reg[s5m8767_irqs[i].reg - 1] & s5m8767_irqs[i].mask)
+			handle_nested_irq(s5m87xx->irq_base + i);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t s5m8763_irq_thread(int irq, void *data)
+{
+	struct s5m87xx_dev *s5m87xx = data;
+	u8 irq_reg[NUM_IRQ_REGS];
+	int ret;
+	int i;
+
+	ret = s5m_bulk_read(s5m87xx, S5M8763_REG_IRQ1,
+				NUM_IRQ_REGS, irq_reg);
+	if (ret < 0) {
+		dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n",
+				ret);
+		return IRQ_NONE;
+	}
+
+	for (i = 0; i < NUM_IRQ_REGS; i++)
+		irq_reg[i] &= ~s5m87xx->irq_masks_cur[i];
+
+	for (i = 0; i < S5M8763_IRQ_NR; i++) {
+		if (irq_reg[s5m8763_irqs[i].reg - 1] & s5m8763_irqs[i].mask)
+			handle_nested_irq(s5m87xx->irq_base + i);
+	}
+
+	return IRQ_HANDLED;
+}
+
+int s5m_irq_resume(struct s5m87xx_dev *s5m87xx)
+{
+	if (s5m87xx->irq && s5m87xx->irq_base){
+		switch (s5m87xx->device_type) {
+		case S5M8763X:
+			s5m8763_irq_thread(s5m87xx->irq_base, s5m87xx);
+			break;
+		case S5M8767X:
+			s5m8767_irq_thread(s5m87xx->irq_base, s5m87xx);
+			break;
+		default:
+			break;
+
+		}
+	}
+	return 0;
+}
+
+int s5m_irq_init(struct s5m87xx_dev *s5m87xx)
+{
+	int i;
+	int cur_irq;
+	int ret = 0;
+	int type = s5m87xx->device_type;
+
+	if (!s5m87xx->irq) {
+		dev_warn(s5m87xx->dev,
+			 "No interrupt specified, no interrupts\n");
+		s5m87xx->irq_base = 0;
+		return 0;
+	}
+
+	if (!s5m87xx->irq_base) {
+		dev_err(s5m87xx->dev,
+			"No interrupt base specified, no interrupts\n");
+		return 0;
+	}
+
+	mutex_init(&s5m87xx->irqlock);
+
+	switch (type) {
+	case S5M8763X:
+		for (i = 0; i < NUM_IRQ_REGS; i++) {
+			s5m87xx->irq_masks_cur[i] = 0xff;
+			s5m87xx->irq_masks_cache[i] = 0xff;
+			s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i,
+						0xff);
+		}
+
+		s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM1, 0xff);
+		s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM2, 0xff);
+
+		for (i = 0; i < S5M8763_IRQ_NR; i++) {
+			cur_irq = i + s5m87xx->irq_base;
+			irq_set_chip_data(cur_irq, s5m87xx);
+			irq_set_chip_and_handler(cur_irq, &s5m8763_irq_chip,
+						 handle_edge_irq);
+			irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+			set_irq_flags(cur_irq, IRQF_VALID);
+#else
+			irq_set_noprobe(cur_irq);
+#endif
+		}
+
+		ret = request_threaded_irq(s5m87xx->irq, NULL,
+					s5m8763_irq_thread,
+					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					"s5m87xx-irq", s5m87xx);
+		if (ret) {
+			dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+				s5m87xx->irq, ret);
+			return ret;
+		}
+		break;
+	case S5M8767X:
+		for (i = 0; i < NUM_IRQ_REGS - 1; i++) {
+			s5m87xx->irq_masks_cur[i] = 0xff;
+			s5m87xx->irq_masks_cache[i] = 0xff;
+			s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i,
+						0xff);
+		}
+
+		for (i = 0; i < S5M8767_IRQ_NR; i++) {
+			cur_irq = i + s5m87xx->irq_base;
+			irq_set_chip_data(cur_irq, s5m87xx);
+			if (ret) {
+				dev_err(s5m87xx->dev,
+					"Failed to irq_set_chip_data %d: %d\n",
+					s5m87xx->irq, ret);
+				return ret;
+			}
+
+			irq_set_chip_and_handler(cur_irq, &s5m8767_irq_chip,
+						 handle_edge_irq);
+			irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+			set_irq_flags(cur_irq, IRQF_VALID);
+#else
+			irq_set_noprobe(cur_irq);
+#endif
+		}
+
+		ret = request_threaded_irq(s5m87xx->irq, NULL,
+					   s5m8767_irq_thread,
+					   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					   "s5m87xx-irq", s5m87xx);
+		if (ret) {
+			dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+				s5m87xx->irq, ret);
+			return ret;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (!s5m87xx->ono)
+		return 0;
+
+	switch (type) {
+	case S5M8763X:
+		ret = request_threaded_irq(s5m87xx->ono, NULL,
+						s5m8763_irq_thread,
+						IRQF_TRIGGER_FALLING |
+						IRQF_TRIGGER_RISING |
+						IRQF_ONESHOT, "s5m87xx-ono",
+						s5m87xx);
+		break;
+	case S5M8767X:
+		ret = request_threaded_irq(s5m87xx->ono, NULL,
+					s5m8767_irq_thread,
+					IRQF_TRIGGER_FALLING |
+					IRQF_TRIGGER_RISING |
+					IRQF_ONESHOT, "s5m87xx-ono", s5m87xx);
+		break;
+	default:
+		break;
+	}
+
+	if (ret)
+		dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+			s5m87xx->ono, ret);
+
+	return 0;
+}
+
+void s5m_irq_exit(struct s5m87xx_dev *s5m87xx)
+{
+	if (s5m87xx->ono)
+		free_irq(s5m87xx->ono, s5m87xx);
+
+	if (s5m87xx->irq)
+		free_irq(s5m87xx->irq, s5m87xx);
+}
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/3] mfd: S5M series initial release
From: Sangbeom Kim @ 2011-10-23  7:29 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie

Samsung is developing various multi function devices.
Currently, 3 devices are announced by samsung.
S5M8767 has pmic and rtc and battery charger.
S5M8763 has pmic, rtc, Li-ion battery charger
S5M8751 has pmic, codec, battery charger, backlight controller.
All devices are designed for mobile applications.
Sequencially, All driver will be posted.
This is initial version for MFD of S5M series.
The other driver will be submitted  separately.

[PATCH 1/3] mfd: Add S5M core driver
[PATCH 2/3] mfd: Add s5m series irq support
[PATCH 3/3] mfd: Add S5M series configuration

^ permalink raw reply

* [PATCH V5 1/3] SDHCI: S3C: Use generic clock names for sdhci bus clock options
From: Kukjin Kim @ 2011-10-24 15:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1318588126-19167-2-git-send-email-rajeshwari.s@samsung.com>

On 10/14/11 12:28, Rajeshwari Shinde wrote:
> This patch modifies the driver to stop depending on the clock names
> being passed from the platform and switch over to bus clock lookup
> using generic clock names.
>
> Signed-off-by: Rajeshwari Shinde<rajeshwari.s@samsung.com>
> ---
>   drivers/mmc/host/sdhci-s3c.c |    6 ++----
>   1 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
> index 82709b6..a5fde87 100644
> --- a/drivers/mmc/host/sdhci-s3c.c
> +++ b/drivers/mmc/host/sdhci-s3c.c
> @@ -435,14 +435,12 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
>
>   	for (clks = 0, ptr = 0; ptr<  MAX_BUS_CLK; ptr++) {
>   		struct clk *clk;
> -		char *name = pdata->clocks[ptr];
> +		char name[14];
>
> -		if (name == NULL)
> -			continue;
> +		sprintf(name, "mmc_busclk.%d", ptr);
>
>   		clk = clk_get(dev, name);
>   		if (IS_ERR(clk)) {
> -			dev_err(dev, "failed to get clock %s\n", name);
>   			continue;
>   		}
>

Looks ok for me.

Chris, if you're ok on this, could you please add this in your tree for 
this merge window? or if you want, I will apply this to Samsung tree 
with other Rajeshwari's patches. I'm ok either...

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* Re: [PATCH V5 1/3] SDHCI: S3C: Use generic clock names for sdhci bus clock options
From: Kukjin Kim @ 2011-10-24 15:16 UTC (permalink / raw)
  To: Rajeshwari Shinde
  Cc: kgene.kim, linux-samsung-soc, linux-mmc, cjb, linux-arm-kernel
In-Reply-To: <1318588126-19167-2-git-send-email-rajeshwari.s@samsung.com>

On 10/14/11 12:28, Rajeshwari Shinde wrote:
> This patch modifies the driver to stop depending on the clock names
> being passed from the platform and switch over to bus clock lookup
> using generic clock names.
>
> Signed-off-by: Rajeshwari Shinde<rajeshwari.s@samsung.com>
> ---
>   drivers/mmc/host/sdhci-s3c.c |    6 ++----
>   1 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
> index 82709b6..a5fde87 100644
> --- a/drivers/mmc/host/sdhci-s3c.c
> +++ b/drivers/mmc/host/sdhci-s3c.c
> @@ -435,14 +435,12 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
>
>   	for (clks = 0, ptr = 0; ptr<  MAX_BUS_CLK; ptr++) {
>   		struct clk *clk;
> -		char *name = pdata->clocks[ptr];
> +		char name[14];
>
> -		if (name == NULL)
> -			continue;
> +		sprintf(name, "mmc_busclk.%d", ptr);
>
>   		clk = clk_get(dev, name);
>   		if (IS_ERR(clk)) {
> -			dev_err(dev, "failed to get clock %s\n", name);
>   			continue;
>   		}
>

Looks ok for me.

Chris, if you're ok on this, could you please add this in your tree for 
this merge window? or if you want, I will apply this to Samsung tree 
with other Rajeshwari's patches. I'm ok either...

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* Re: [PATCH 07/10] RDMA/cxgb4: DB Drop Recovery for RDMA and LLD queues.
From: Vipul Pandya @ 2011-10-24 15:16 UTC (permalink / raw)
  To: David Miller
  Cc: swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW,
	roland-BHEL68pLQRGGvPXPguhicg, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, divy-ut6Up61K2wZBDgjK7y7TUQ,
	dm-ut6Up61K2wZBDgjK7y7TUQ, kumaras-ut6Up61K2wZBDgjK7y7TUQ
In-Reply-To: <20111020.165703.1713724038045504243.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>



On 21-10-2011 02:27, David Miller wrote:

> From: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>
> Date: Thu, 20 Oct 2011 12:28:07 -0500
> 
>> On 10/20/2011 12:17 PM, Roland Dreier wrote:
>>>> I believe 5 and 7 have build dependencies.
>>> Right, missed that one too.
>>>
>>> But it seems 4,6,8,9,10 are independent of the rest of the series?
>>>
>>> ie I can trivially apply them and then worry about working out
>>> the drivers/net / drivers/infiniband interdependency a bit later?
>>>
>>
>> Some of these might be dependent on prior patches the series.  But if
>> they aren't, yes, you could do that.
> 
> So, how do you guys want to do this?  If you give me a list of which
> patches I should put into net-next and leave the rest to the infiniband
> tree, that'd work fine for me as long as net-next is left in a working
> state independent of the infiniband tree.


Hi Dave Miller/Roland,

With respect to above dependencies we did some experiments and found
following things

1. We can apply three cxgb4 patches, 01 02 and 03, on net-next tree
successfully and build it.

2. Out of 7 RDMA/cxgb4 patches only 04, 08 and 10 can be applied
trivially and driver can be built successfully. If we try to apply
remaining patches, 05 06 07 and 09, either they will fail to apply or
give build failure. Moreover patches 05, 06, 07 and 09 can be applied on
top of 04, 08 and 10 cleanly.

Based on above results we would like to propose following two things.

1. We would like to recommend that all the patches get included in
Roland's infiniband tree since it has build dependencies.

2. Alternatively,
- Patches 01, 02 and 03 can be included in net-next tree.
- Patches 04, 08 and 10 can be included in Roland's infiniband tree at
present.
- Patches 05, 06, 07 and 09 have to wait till the net-next hits the
3.2-rc1.

Please let us know if you have any other suggestions.

Thanks,
Vipul
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: kdump: crash_kexec()-smp_send_stop() race in panic
From: Eric W. Biederman @ 2011-10-24 15:14 UTC (permalink / raw)
  To: holzheu; +Cc: heiko.carstens, kexec, linux-kernel, schwidefsky, akpm,
	Vivek Goyal
In-Reply-To: <1319468137.3615.16.camel@br98xy6r>

Michael Holzheu <holzheu@linux.vnet.ibm.com> writes:

> Hello Vivek,
>
> In our tests we ran into the following scenario:
>
> Two CPUs have called panic at the same time. The first CPU called
> crash_kexec() and the second CPU called smp_send_stop() in panic()
> before crash_kexec() finished on the first CPU. So the second CPU
> stopped the first CPU and therefore kdump failed.
>
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
>
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>        ->smp_send_stop()-> stop CPU 1 (stop kdump)
>
> How should we fix this problem? One possibility could be to do
> smp_send_stop() before we call crash_kexec().
>
> What do you think?

smp_send_stop is insufficiently reliable to be used before crash_kexec.

My first reaction would be to test oops_in_progress and wait until
oops_in_progress == 1 before calling smp_send_stop.

Eric

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply

* Re: [PATCH] usb: fix unaligned access
From: Antony Pavlov @ 2011-10-24 15:14 UTC (permalink / raw)
  To: Fabian van der Werf; +Cc: barebox
In-Reply-To: <CAJeSw6Be=2jNOw1SSz1xB-7bXL9RyrUuLz+yWcZvxfNap6RkwQ@mail.gmail.com>

On 23 October 2011 13:29, Fabian van der Werf <fvanderwerf@gmail.com> wrote:
>>
>> Looks like a valid patch, I wonder that this never was a problem before.
>> ARM should break here aswell I think. What architecture are you using?
>>
>
> I am working with a pandaboard (arm cortex a9). The pandaboard has a
> usb ethernet controller, so I need usb to boot over tftp. I guess that
> most arm configurations don't need usb for booting, and in that case
> you won't run into this problem.

I have DUB-E100 USB Ethernet (ID 2001:3c05) connected to Toshiba AC100
(NVidia Tegra2 --- Cortex A9); tftp works fine without usb unaligned
access patch.

-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply

* [PATCHES] dm-crypt parallelization
From: Mikulas Patocka @ 2011-10-24 15:14 UTC (permalink / raw)
  To: Alasdair G. Kergon, Milan Broz; +Cc: dm-devel

Hi

Here are patches for dm-crypt parallelization: 
http://people.redhat.com/mpatocka/patches/kernel/dm-crypt-paralelizace/

For each cpu, we create a kernel thread bound to that cpu. There is a 
global queue with sectors to be encrypted. We add requests to the queue 
and wake the per-cpu-threads. The threads pop requests from the queue and 
process them.

Mikulas

^ permalink raw reply

* Re: [PATCH] sparse, llvm: Fix 'void *' pointer code generation
From: Jeff Garzik @ 2011-10-24 15:13 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Jonathan Neuschäfer, Linus Torvalds, Pekka Enberg,
	linux-sparse, Christopher Li, Jeff Garzik
In-Reply-To: <alpine.LFD.2.02.1110241532340.14239@tux.localdomain>

On 10/24/2011 08:33 AM, Pekka Enberg wrote:
>> On Mon, Oct 24, 2011 at 02:56:41PM +0300, Pekka Enberg wrote:
>>> Fix the issue by switching to LLVMIntType(bits_per_pointer) in
>>> sym_basetype_type().
>
> On Mon, 24 Oct 2011, Jonathan Neuschäfer wrote:
>> You didn't update the commit message.
>
> Thanks for pointing that out. Jeff, does this look OK?

I don't know what bit_size==-1 means off the top of my head, so I assume 
yes ;-)

	Jeff




--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: kdump: crash_kexec()-smp_send_stop() race in panic
From: Eric W. Biederman @ 2011-10-24 15:14 UTC (permalink / raw)
  To: holzheu; +Cc: Vivek Goyal, akpm, schwidefsky, heiko.carstens, kexec,
	linux-kernel
In-Reply-To: <1319468137.3615.16.camel@br98xy6r>

Michael Holzheu <holzheu@linux.vnet.ibm.com> writes:

> Hello Vivek,
>
> In our tests we ran into the following scenario:
>
> Two CPUs have called panic at the same time. The first CPU called
> crash_kexec() and the second CPU called smp_send_stop() in panic()
> before crash_kexec() finished on the first CPU. So the second CPU
> stopped the first CPU and therefore kdump failed.
>
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
>
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>        ->smp_send_stop()-> stop CPU 1 (stop kdump)
>
> How should we fix this problem? One possibility could be to do
> smp_send_stop() before we call crash_kexec().
>
> What do you think?

smp_send_stop is insufficiently reliable to be used before crash_kexec.

My first reaction would be to test oops_in_progress and wait until
oops_in_progress == 1 before calling smp_send_stop.

Eric

^ permalink raw reply

* Re: [Qemu-devel] [PATCH 1/5] monitor: screen_dump async
From: Gerd Hoffmann @ 2011-10-24 15:13 UTC (permalink / raw)
  To: Alon Levy; +Cc: qemu-devel, mlureau, armbru, lcapitulino
In-Reply-To: <1319457739-14562-2-git-send-email-alevy@redhat.com>

On 10/24/11 14:02, Alon Levy wrote:
> Make screen_dump monitor command an async command to allow next for qxl
> to implement it as a initiating call to red_worker and completion on
> callback, to fix a deadlock when issueing a screendump command via
> libvirt while connected with a libvirt controlled spice-gtk client.

Approach looks reasonable to me.  Patch breaks the build though, you've
missed a bunch of screen_dump functions in non-x86 targets.

cheers,
  Gerd

^ permalink raw reply

* Re: [Qemu-devel] [PATCH 15/24] block: switch bdrv_read()/bdrv_write() to coroutines
From: Pierre Riteau @ 2011-10-24 15:12 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: Kevin Wolf, qemu-devel
In-Reply-To: <1318610959-17971-16-git-send-email-kwolf@redhat.com>

This commit (1c9805a398cc1125b4defa6367172c8c2c0bca9f in Git) breaks qemu-nbd for me. I cannot mount any VM image (raw or qcow2 format) with this commit or today's HEAD. Previous commit c5fbe57111ef59c315a71cd80e8b0af59e36ff21 works fine.

The qemu-nbd process hangs while reading disk:

31175 ?        Ss     0:00 qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw
31176 ?        S      0:00  \_ qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw
31177 ?        D      0:00  \_ qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw

In dmesg I see only:

[18304.541058]  nbd0:

Then, if I pkill -9 nbd, dmesg gets more verbose:

[18467.288183] nbd (pid 31175: qemu-nbd) got signal 9
[18467.303175] nbd0: shutting down socket
[18467.314446] nbd0: Receive control failed (result -4)
[18467.329354] end_request: I/O error, dev nbd0, sector 0
[18467.344771] __ratelimit: 38 callbacks suppressed
[18467.358620] Buffer I/O error on device nbd0, logical block 0
[18467.375591] Buffer I/O error on device nbd0, logical block 1
[18467.392560] Buffer I/O error on device nbd0, logical block 2
[18467.409530] Buffer I/O error on device nbd0, logical block 3
[18467.426508] nbd0: queue cleared
[18467.435962] nbd0: Attempted send on closed socket
[18467.450095] end_request: I/O error, dev nbd0, sector 0
[18467.465527] Buffer I/O error on device nbd0, logical block 0
[18467.482496] Buffer I/O error on device nbd0, logical block 1
[18467.499464] Buffer I/O error on device nbd0, logical block 2
[18467.516433] Buffer I/O error on device nbd0, logical block 3
[18467.533418] nbd0: Attempted send on closed socket
[18467.547539] end_request: I/O error, dev nbd0, sector 0
[18467.562945] Buffer I/O error on device nbd0, logical block 0
[18467.579917] Buffer I/O error on device nbd0, logical block 1
[18467.596897] nbd0: Attempted send on closed socket
[18467.611022] end_request: I/O error, dev nbd0, sector 0
[18467.626442] nbd0: Attempted send on closed socket
[18467.640569] end_request: I/O error, dev nbd0, sector 0
[18467.655984] ldm_validate_partition_table(): Disk read failed.
[18467.673242] nbd0: Attempted send on closed socket
[18467.687369] end_request: I/O error, dev nbd0, sector 0
[18467.702788] nbd0: Attempted send on closed socket
[18467.716915] end_request: I/O error, dev nbd0, sector 0
[18467.732359] nbd0: Attempted send on closed socket
[18467.746487] end_request: I/O error, dev nbd0, sector 0
[18467.761931] nbd0: Attempted send on closed socket
[18467.776058] end_request: I/O error, dev nbd0, sector 0
[18467.791473] Dev nbd0: unable to read RDB block 0
[18467.805348] nbd0: Attempted send on closed socket
[18467.819479] end_request: I/O error, dev nbd0, sector 0
[18467.834897] nbd0: Attempted send on closed socket
[18467.849025] end_request: I/O error, dev nbd0, sector 0
[18467.864446] nbd0: Attempted send on closed socket
[18467.878572] end_request: I/O error, dev nbd0, sector 0
[18467.893985]  unable to read partition table

-- 
Pierre Riteau -- PhD student, Myriads team, IRISA, Rennes, France
http://perso.univ-rennes1.fr/pierre.riteau/

On 14 oct. 2011, at 18:49, Kevin Wolf wrote:

> From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> 
> The bdrv_read()/bdrv_write() functions call .bdrv_read()/.bdrv_write().
> They should go through bdrv_co_do_readv() and bdrv_co_do_writev()
> instead in order to unify request processing code across sync, aio, and
> coroutine interfaces.  This is also an important step towards removing
> BlockDriverState .bdrv_read()/.bdrv_write() in the future.
> 
> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
> block.c |  112 +++++++++++++++++++++++++++++++++++----------------------------
> 1 files changed, 62 insertions(+), 50 deletions(-)
> 
> diff --git a/block.c b/block.c
> index f4731ec..ae8fc80 100644
> --- a/block.c
> +++ b/block.c
> @@ -44,6 +44,8 @@
> #include <windows.h>
> #endif
> 
> +#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
> +
> static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
> static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
>         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
> @@ -74,6 +76,8 @@ static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
> static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
> static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
>     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
> +static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
> +    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
> 
> static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
>     QTAILQ_HEAD_INITIALIZER(bdrv_states);
> @@ -1042,30 +1046,69 @@ static inline bool bdrv_has_async_flush(BlockDriver *drv)
>     return drv->bdrv_aio_flush != bdrv_aio_flush_em;
> }
> 
> -/* return < 0 if error. See bdrv_write() for the return codes */
> -int bdrv_read(BlockDriverState *bs, int64_t sector_num,
> -              uint8_t *buf, int nb_sectors)
> +typedef struct RwCo {
> +    BlockDriverState *bs;
> +    int64_t sector_num;
> +    int nb_sectors;
> +    QEMUIOVector *qiov;
> +    bool is_write;
> +    int ret;
> +} RwCo;
> +
> +static void coroutine_fn bdrv_rw_co_entry(void *opaque)
> {
> -    BlockDriver *drv = bs->drv;
> +    RwCo *rwco = opaque;
> 
> -    if (!drv)
> -        return -ENOMEDIUM;
> +    if (!rwco->is_write) {
> +        rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
> +                                     rwco->nb_sectors, rwco->qiov);
> +    } else {
> +        rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
> +                                      rwco->nb_sectors, rwco->qiov);
> +    }
> +}
> 
> -    if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) {
> -        QEMUIOVector qiov;
> -        struct iovec iov = {
> -            .iov_base = (void *)buf,
> -            .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
> -        };
> +/*
> + * Process a synchronous request using coroutines
> + */
> +static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
> +                      int nb_sectors, bool is_write)
> +{
> +    QEMUIOVector qiov;
> +    struct iovec iov = {
> +        .iov_base = (void *)buf,
> +        .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
> +    };
> +    Coroutine *co;
> +    RwCo rwco = {
> +        .bs = bs,
> +        .sector_num = sector_num,
> +        .nb_sectors = nb_sectors,
> +        .qiov = &qiov,
> +        .is_write = is_write,
> +        .ret = NOT_DONE,
> +    };
> 
> -        qemu_iovec_init_external(&qiov, &iov, 1);
> -        return bdrv_co_readv(bs, sector_num, nb_sectors, &qiov);
> -    }
> +    qemu_iovec_init_external(&qiov, &iov, 1);
> 
> -    if (bdrv_check_request(bs, sector_num, nb_sectors))
> -        return -EIO;
> +    if (qemu_in_coroutine()) {
> +        /* Fast-path if already in coroutine context */
> +        bdrv_rw_co_entry(&rwco);
> +    } else {
> +        co = qemu_coroutine_create(bdrv_rw_co_entry);
> +        qemu_coroutine_enter(co, &rwco);
> +        while (rwco.ret == NOT_DONE) {
> +            qemu_aio_wait();
> +        }
> +    }
> +    return rwco.ret;
> +}
> 
> -    return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
> +/* return < 0 if error. See bdrv_write() for the return codes */
> +int bdrv_read(BlockDriverState *bs, int64_t sector_num,
> +              uint8_t *buf, int nb_sectors)
> +{
> +    return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
> }
> 
> static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
> @@ -1105,36 +1148,7 @@ static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
> int bdrv_write(BlockDriverState *bs, int64_t sector_num,
>                const uint8_t *buf, int nb_sectors)
> {
> -    BlockDriver *drv = bs->drv;
> -
> -    if (!bs->drv)
> -        return -ENOMEDIUM;
> -
> -    if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) {
> -        QEMUIOVector qiov;
> -        struct iovec iov = {
> -            .iov_base = (void *)buf,
> -            .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
> -        };
> -
> -        qemu_iovec_init_external(&qiov, &iov, 1);
> -        return bdrv_co_writev(bs, sector_num, nb_sectors, &qiov);
> -    }
> -
> -    if (bs->read_only)
> -        return -EACCES;
> -    if (bdrv_check_request(bs, sector_num, nb_sectors))
> -        return -EIO;
> -
> -    if (bs->dirty_bitmap) {
> -        set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
> -    }
> -
> -    if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
> -        bs->wr_highest_sector = sector_num + nb_sectors - 1;
> -    }
> -
> -    return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
> +    return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
> }
> 
> int bdrv_pread(BlockDriverState *bs, int64_t offset,
> @@ -2912,8 +2926,6 @@ static void bdrv_rw_em_cb(void *opaque, int ret)
>     *(int *)opaque = ret;
> }
> 
> -#define NOT_DONE 0x7fffffff
> -
> static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
>                         uint8_t *buf, int nb_sectors)
> {
> -- 
> 1.7.6.4
> 
> 

^ permalink raw reply

* Re: [PATCH V2 09/11] libxl_json, Handle number abrove LONG_MAX.
From: Anthony PERARD @ 2011-10-24 15:12 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Xen Devel, Stefano Stabellini
In-Reply-To: <1319450257.3385.175.camel@zakaz.uk.xensource.com>

On Mon, Oct 24, 2011 at 10:57, Ian Campbell <Ian.Campbell@citrix.com> wrote:
> On Thu, 2011-10-20 at 18:59 +0100, Anthony PERARD wrote:
>> The integers are now "long long" in the json_object. If strtoll failed to
>> convert a string into a number, the number is stored as it (a char*).
>>
>> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
>> ---
>>  tools/libxl/libxl_internal.h |    7 +++--
>>  tools/libxl/libxl_json.c     |   52 +++++++++++++++++++++++------------------
>>  2 files changed, 33 insertions(+), 26 deletions(-)
>>
>> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
>> index 5720b31..849b251 100644
>> --- a/tools/libxl/libxl_internal.h
>> +++ b/tools/libxl/libxl_internal.h
>> @@ -465,7 +465,8 @@ typedef enum {
>>      JSON_TRUE,
>>      JSON_FALSE,
>>      JSON_INTEGER,
>> -    JSON_DOUBLE,
>
> Did you accidentally remove this ...
>
>> +    /* number is store in string, it's too big to be a long long */
>> +    JSON_NUMBER,
>>      JSON_STRING,
>>      JSON_MAP,
>>      JSON_ARRAY,
>> @@ -475,7 +476,7 @@ typedef enum {
>>  typedef struct libxl__json_object {
>>      libxl__json_node_type type;
>>      union {
>> -        long i;
>> +        long long i;
>>          double d;
>
> ... or accidentally leave this?

I've accidentally leave this double, because I do not handle float
number as I do'nt need them yet. But I probably should parse them as
well, and keep double in the structure.

>>          char *string;
>>          /* List of libxl__json_object */
>> @@ -534,7 +535,7 @@ flexarray_t *libxl__json_object_get_array(const libxl__json_object *o)
>>      else
>>          return NULL;
>>  }
>> -static inline long libxl__json_object_get_integer(const libxl__json_object *o)
>> +static inline long long libxl__json_object_get_integer(const libxl__json_object *o)
>>  {
>>      if (libxl__json_object_is_integer(o))
>>          return o->u.i;
>> diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
>> index c743114..2d8f61e 100644
>> --- a/tools/libxl/libxl_json.c
>> +++ b/tools/libxl/libxl_json.c
>> @@ -44,6 +44,7 @@ struct libxl__yajl_ctx {
>>  #  define DEBUG_GEN(ctx, type)              yajl_gen_##type(ctx->g)
>>  #  define DEBUG_GEN_VALUE(ctx, type, value) yajl_gen_##type(ctx->g, value)
>>  #  define DEBUG_GEN_STRING(ctx, str, n)     yajl_gen_string(ctx->g, str, n)
>> +#  define DEBUG_GEN_NUMBER(ctx, str, n)     yajl_gen_number(ctx->g, str, n)
>>  #  define DEBUG_GEN_REPORT(yajl_ctx) \
>>      do { \
>>          const unsigned char *buf = NULL; \
>> @@ -60,6 +61,7 @@ struct libxl__yajl_ctx {
>>  #  define DEBUG_GEN(ctx, type)                  ((void)0)
>>  #  define DEBUG_GEN_VALUE(ctx, type, value)     ((void)0)
>>  #  define DEBUG_GEN_STRING(ctx, value, lenght)  ((void)0)
>> +#  define DEBUG_GEN_NUMBER(ctx, value, lenght)  ((void)0)
>
> that typo got propagated...
>
>>  #  define DEBUG_GEN_REPORT(ctx)                 ((void)0)
>>  #endif
>>
>> @@ -363,6 +365,7 @@ void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj)
>>          return;
>>      switch (obj->type) {
>>      case JSON_STRING:
>> +    case JSON_NUMBER:
>>          free(obj->u.string);
>>          break;
>>      case JSON_MAP: {
>> @@ -504,35 +507,38 @@ static int json_callback_boolean(void *opaque, int boolean)
>>      return 1;
>>  }
>>
>> -static int json_callback_integer(void *opaque, long value)
>> +static int json_callback_number(void *opaque, const char *s, unsigned int len)
>>  {
>>      libxl__yajl_ctx *ctx = opaque;
>> -    libxl__json_object *obj;
>> -
>> -    DEBUG_GEN_VALUE(ctx, integer, value);
>> +    libxl__json_object *obj = NULL;
>> +    long long i;
>>
>> -    if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL)
>> -        return 0;
>> -    obj->u.i = value;
>> +    /* should be replace by number */
>> +    DEBUG_GEN_NUMBER(ctx, s, len);
>>
>> -    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
>> -        libxl__json_object_free(ctx->gc, obj);
>> -        return 0;
>> -    }
>> +    i = strtoll(s, NULL, 10);
>>
>> -    return 1;
>> -}
>> +    if ((i == LLONG_MIN || i == LLONG_MAX) && errno == ERANGE) {
>> +        char *t = NULL;
>>
>> -static int json_callback_double(void *opaque, double value)
>> -{
>> -    libxl__yajl_ctx *ctx = opaque;
>> -    libxl__json_object *obj;
>> +        if ((obj = json_object_alloc(ctx->gc, JSON_NUMBER)) == NULL)
>> +            return 0;
>>
>> -    DEBUG_GEN_VALUE(ctx, double, value);
>> +        t = malloc(len + 1);
>> +        if (t == NULL) {
>> +            LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
>> +                             "Failed to allocate");
>> +            return 0;
>> +        }
>> +        strncpy(t, s, len);
>> +        t[len] = 0;
>>
>> -    if ((obj = json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL)
>> -        return 0;
>> -    obj->u.d = value;
>> +        obj->u.string = t;
>> +    } else {
>> +        if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL)
>> +            return 0;
>> +        obj->u.i = i;
>> +    }
>>
>>      if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
>>          libxl__json_object_free(ctx->gc, obj);
>> @@ -706,9 +712,9 @@ static int json_callback_end_array(void *opaque)
>>  static yajl_callbacks callbacks = {
>>      json_callback_null,
>>      json_callback_boolean,
>> -    json_callback_integer,
>> -    json_callback_double,
>>      NULL,
>> +    NULL,
>> +    json_callback_number,
>>      json_callback_string,
>>      json_callback_start_map,
>>      json_callback_map_key,
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
>



-- 
Anthony PERARD

^ permalink raw reply

* [PATCH V2 05/10] RDMA/cxgb4: Add DB Overflow Avoidance.
From: Vipul Pandya @ 2011-10-24 15:12 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: roland-BHEL68pLQRGGvPXPguhicg, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	divy-ut6Up61K2wZBDgjK7y7TUQ, dm-ut6Up61K2wZBDgjK7y7TUQ,
	kumaras-ut6Up61K2wZBDgjK7y7TUQ,
	swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW, Vipul Pandya

        - get FULL/EMPTY/DROP events from LLD

        - on FULL event, disable normal user mode DB rings.

        - add modify_qp semantics to allow user processes to call into
        the kernel to ring doobells without overflowing.

        Add DB Full/Empty/Drop stats.

        Mark queues when created indicating the doorbell state.

        If we're in the middle of db overflow avoidance, then newly created
        queues should start out in this mode.

        Bump the C4IW_UVERBS_ABI_VERSION to 2 so the user mode library can
        know if the driver supports the kernel mode db ringing.

Signed-off-by: Vipul Pandya <vipul-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>
---
V2: Bump C4IW_UVERBS_ABI_VERSION to 2

 drivers/infiniband/hw/cxgb4/device.c   |   84 +++++++++++++++++++++++++++++--
 drivers/infiniband/hw/cxgb4/iw_cxgb4.h |   37 ++++++++++++--
 drivers/infiniband/hw/cxgb4/qp.c       |   51 +++++++++++++++++++-
 drivers/infiniband/hw/cxgb4/user.h     |    2 +-
 4 files changed, 162 insertions(+), 12 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 8483111..9062ed9 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -44,6 +44,12 @@ MODULE_DESCRIPTION("Chelsio T4 RDMA Driver");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(DRV_VERSION);
 
+struct uld_ctx {
+	struct list_head entry;
+	struct cxgb4_lld_info lldi;
+	struct c4iw_dev *dev;
+};
+
 static LIST_HEAD(uld_ctx_list);
 static DEFINE_MUTEX(dev_mutex);
 
@@ -263,6 +269,9 @@ static int stats_show(struct seq_file *seq, void *v)
 	seq_printf(seq, "  OCQPMEM: %10llu %10llu %10llu\n",
 			dev->rdev.stats.ocqp.total, dev->rdev.stats.ocqp.cur,
 			dev->rdev.stats.ocqp.max);
+	seq_printf(seq, "  DB FULL: %10llu\n", dev->rdev.stats.db_full);
+	seq_printf(seq, " DB EMPTY: %10llu\n", dev->rdev.stats.db_empty);
+	seq_printf(seq, "  DB DROP: %10llu\n", dev->rdev.stats.db_drop);
 	return 0;
 }
 
@@ -283,6 +292,9 @@ static ssize_t stats_clear(struct file *file, const char __user *buf,
 	dev->rdev.stats.pbl.max = 0;
 	dev->rdev.stats.rqt.max = 0;
 	dev->rdev.stats.ocqp.max = 0;
+	dev->rdev.stats.db_full = 0;
+	dev->rdev.stats.db_empty = 0;
+	dev->rdev.stats.db_drop = 0;
 	mutex_unlock(&dev->rdev.stats.lock);
 	return count;
 }
@@ -443,12 +455,6 @@ static void c4iw_rdev_close(struct c4iw_rdev *rdev)
 	c4iw_destroy_resource(&rdev->resource);
 }
 
-struct uld_ctx {
-	struct list_head entry;
-	struct cxgb4_lld_info lldi;
-	struct c4iw_dev *dev;
-};
-
 static void c4iw_dealloc(struct uld_ctx *ctx)
 {
 	c4iw_rdev_close(&ctx->dev->rdev);
@@ -514,6 +520,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
 	idr_init(&devp->mmidr);
 	spin_lock_init(&devp->lock);
 	mutex_init(&devp->rdev.stats.lock);
+	mutex_init(&devp->db_mutex);
 
 	if (c4iw_debugfs_root) {
 		devp->debugfs_root = debugfs_create_dir(
@@ -659,11 +666,76 @@ static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state)
 	return 0;
 }
 
+static int disable_qp_db(int id, void *p, void *data)
+{
+	struct c4iw_qp *qp = p;
+
+	t4_disable_wq_db(&qp->wq);
+	return 0;
+}
+
+static void stop_queues(struct uld_ctx *ctx)
+{
+	spin_lock_irq(&ctx->dev->lock);
+	ctx->dev->db_state = FLOW_CONTROL;
+	idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL);
+	spin_unlock_irq(&ctx->dev->lock);
+}
+
+static int enable_qp_db(int id, void *p, void *data)
+{
+	struct c4iw_qp *qp = p;
+
+	t4_enable_wq_db(&qp->wq);
+	return 0;
+}
+
+static void resume_queues(struct uld_ctx *ctx)
+{
+	spin_lock_irq(&ctx->dev->lock);
+	ctx->dev->db_state = NORMAL;
+	idr_for_each(&ctx->dev->qpidr, enable_qp_db, NULL);
+	spin_unlock_irq(&ctx->dev->lock);
+}
+
+static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...)
+{
+	struct uld_ctx *ctx = handle;
+
+	switch (control) {
+	case CXGB4_CONTROL_DB_FULL:
+		stop_queues(ctx);
+		mutex_lock(&ctx->dev->rdev.stats.lock);
+		ctx->dev->rdev.stats.db_full++;
+		mutex_unlock(&ctx->dev->rdev.stats.lock);
+		break;
+	case CXGB4_CONTROL_DB_EMPTY:
+		resume_queues(ctx);
+		mutex_lock(&ctx->dev->rdev.stats.lock);
+		ctx->dev->rdev.stats.db_empty++;
+		mutex_unlock(&ctx->dev->rdev.stats.lock);
+		break;
+	case CXGB4_CONTROL_DB_DROP:
+		printk(KERN_WARNING MOD "%s: Fatal DB DROP\n",
+		       pci_name(ctx->lldi.pdev));
+		mutex_lock(&ctx->dev->rdev.stats.lock);
+		ctx->dev->rdev.stats.db_drop++;
+		mutex_unlock(&ctx->dev->rdev.stats.lock);
+		break;
+	default:
+		printk(KERN_WARNING MOD "%s: unknown control cmd %u\n",
+		       pci_name(ctx->lldi.pdev), control);
+		break;
+	}
+	return 0;
+}
+
 static struct cxgb4_uld_info c4iw_uld_info = {
 	.name = DRV_NAME,
 	.add = c4iw_uld_add,
 	.rx_handler = c4iw_uld_rx_handler,
 	.state_change = c4iw_uld_state_change,
+	.control = c4iw_uld_control,
 };
 
 static int __init c4iw_init_module(void)
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index ec7c848..1924c19 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -117,6 +117,9 @@ struct c4iw_stats {
 	struct c4iw_stat pbl;
 	struct c4iw_stat rqt;
 	struct c4iw_stat ocqp;
+	u64  db_full;
+	u64  db_empty;
+	u64  db_drop;
 };
 
 struct c4iw_rdev {
@@ -192,6 +195,12 @@ static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev,
 	return wr_waitp->ret;
 }
 
+enum db_state {
+	NORMAL = 0,
+	FLOW_CONTROL = 1,
+	RECOVERY = 2
+};
+
 struct c4iw_dev {
 	struct ib_device ibdev;
 	struct c4iw_rdev rdev;
@@ -200,7 +209,9 @@ struct c4iw_dev {
 	struct idr qpidr;
 	struct idr mmidr;
 	spinlock_t lock;
+	struct mutex db_mutex;
 	struct dentry *debugfs_root;
+	enum db_state db_state;
 };
 
 static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)
@@ -228,8 +239,8 @@ static inline struct c4iw_mr *get_mhp(struct c4iw_dev *rhp, u32 mmid)
 	return idr_find(&rhp->mmidr, mmid);
 }
 
-static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
-				void *handle, u32 id)
+static inline int _insert_handle(struct c4iw_dev *rhp, struct idr *idr,
+				 void *handle, u32 id, int lock)
 {
 	int ret;
 	int newid;
@@ -237,15 +248,29 @@ static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
 	do {
 		if (!idr_pre_get(idr, GFP_KERNEL))
 			return -ENOMEM;
-		spin_lock_irq(&rhp->lock);
+		if (lock)
+			spin_lock_irq(&rhp->lock);
 		ret = idr_get_new_above(idr, handle, id, &newid);
 		BUG_ON(newid != id);
-		spin_unlock_irq(&rhp->lock);
+		if (lock)
+			spin_unlock_irq(&rhp->lock);
 	} while (ret == -EAGAIN);
 
 	return ret;
 }
 
+static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
+				void *handle, u32 id)
+{
+	return _insert_handle(rhp, idr, handle, id, 1);
+}
+
+static inline int insert_handle_nolock(struct c4iw_dev *rhp, struct idr *idr,
+				       void *handle, u32 id)
+{
+	return _insert_handle(rhp, idr, handle, id, 0);
+}
+
 static inline void remove_handle(struct c4iw_dev *rhp, struct idr *idr, u32 id)
 {
 	spin_lock_irq(&rhp->lock);
@@ -369,6 +394,8 @@ struct c4iw_qp_attributes {
 	struct c4iw_ep *llp_stream_handle;
 	u8 layer_etype;
 	u8 ecode;
+	u16 sq_db_inc;
+	u16 rq_db_inc;
 };
 
 struct c4iw_qp {
@@ -443,6 +470,8 @@ static inline void insert_mmap(struct c4iw_ucontext *ucontext,
 
 enum c4iw_qp_attr_mask {
 	C4IW_QP_ATTR_NEXT_STATE = 1 << 0,
+	C4IW_QP_ATTR_SQ_DB = 1<<1,
+	C4IW_QP_ATTR_RQ_DB = 1<<2,
 	C4IW_QP_ATTR_ENABLE_RDMA_READ = 1 << 7,
 	C4IW_QP_ATTR_ENABLE_RDMA_WRITE = 1 << 8,
 	C4IW_QP_ATTR_ENABLE_RDMA_BIND = 1 << 9,
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index 74df98e..36fc94d 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -34,6 +34,10 @@
 
 #include "iw_cxgb4.h"
 
+static int db_delay_usecs = 1;
+module_param(db_delay_usecs, int, 0644);
+MODULE_PARM_DESC(db_delay_usecs, "Usecs to delay awaiting db fifo to drain");
+
 static int ocqp_support = 1;
 module_param(ocqp_support, int, 0644);
 MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=1)");
@@ -1117,6 +1121,29 @@ out:
 	return ret;
 }
 
+/*
+ * Called by the library when the qp has user dbs disabled due to
+ * a DB_FULL condition.  This function will single-thread all user
+ * DB rings to avoid overflowing the hw db-fifo.
+ */
+static int ring_kernel_db(struct c4iw_qp *qhp, u32 qid, u16 inc)
+{
+	int delay = db_delay_usecs;
+
+	mutex_lock(&qhp->rhp->db_mutex);
+	do {
+		if (cxgb4_dbfifo_count(qhp->rhp->rdev.lldi.ports[0], 1) < 768) {
+			writel(V_QID(qid) | V_PIDX(inc), qhp->wq.db);
+			break;
+		}
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(usecs_to_jiffies(delay));
+		delay = min(delay << 1, 200000);
+	} while (1);
+	mutex_unlock(&qhp->rhp->db_mutex);
+	return 0;
+}
+
 int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
 		   enum c4iw_qp_attr_mask mask,
 		   struct c4iw_qp_attributes *attrs,
@@ -1165,6 +1192,15 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
 		qhp->attr = newattr;
 	}
 
+	if (mask & C4IW_QP_ATTR_SQ_DB) {
+		ret = ring_kernel_db(qhp, qhp->wq.sq.qid, attrs->sq_db_inc);
+		goto out;
+	}
+	if (mask & C4IW_QP_ATTR_RQ_DB) {
+		ret = ring_kernel_db(qhp, qhp->wq.rq.qid, attrs->rq_db_inc);
+		goto out;
+	}
+
 	if (!(mask & C4IW_QP_ATTR_NEXT_STATE))
 		goto out;
 	if (qhp->attr.state == attrs->next_state)
@@ -1454,7 +1490,11 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
 	init_waitqueue_head(&qhp->wait);
 	atomic_set(&qhp->refcnt, 1);
 
-	ret = insert_handle(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
+	spin_lock_irq(&rhp->lock);
+	if (rhp->db_state != NORMAL)
+		t4_disable_wq_db(&qhp->wq);
+	ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
+	spin_unlock_irq(&rhp->lock);
 	if (ret)
 		goto err2;
 
@@ -1598,6 +1638,15 @@ int c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 			 C4IW_QP_ATTR_ENABLE_RDMA_WRITE |
 			 C4IW_QP_ATTR_ENABLE_RDMA_BIND) : 0;
 
+	/*
+	 * Use SQ_PSN and RQ_PSN to pass in IDX_INC values for
+	 * ringing the queue db when we're in DB_FULL mode.
+	 */
+	attrs.sq_db_inc = attr->sq_psn;
+	attrs.rq_db_inc = attr->rq_psn;
+	mask |= (attr_mask & IB_QP_SQ_PSN) ? C4IW_QP_ATTR_SQ_DB : 0;
+	mask |= (attr_mask & IB_QP_RQ_PSN) ? C4IW_QP_ATTR_RQ_DB : 0;
+
 	return c4iw_modify_qp(rhp, qhp, mask, &attrs, 0);
 }
 
diff --git a/drivers/infiniband/hw/cxgb4/user.h b/drivers/infiniband/hw/cxgb4/user.h
index e6669d5..32b754c 100644
--- a/drivers/infiniband/hw/cxgb4/user.h
+++ b/drivers/infiniband/hw/cxgb4/user.h
@@ -32,7 +32,7 @@
 #ifndef __C4IW_USER_H__
 #define __C4IW_USER_H__
 
-#define C4IW_UVERBS_ABI_VERSION	1
+#define C4IW_UVERBS_ABI_VERSION	2
 
 /*
  * Make sure that all structs defined in this file remain laid out so
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: Channel-less IIO events
From: Jonathan Cameron @ 2011-10-24 15:12 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: linux-iio@vger.kernel.org
In-Reply-To: <4EA57EB6.1020801@metafoo.de>

On 10/24/11 16:05, Lars-Peter Clausen wrote:
> On 10/24/2011 04:25 PM, Jonathan Cameron wrote:
>> On 10/24/11 14:47, Lars-Peter Clausen wrote:
>>> Hi,
>>>
>>> Some chips generate events which don't really map to a channel, but are
>>> rather chip global. For example over-temperature events.
>> That one is a channel.
>>> Do you think this is something we should add support for or should we rather
>>> use a dummy channel, which doesn't report any actual values, for propagating
>>> the event?
>> Yup, have a temp channel for that one.  Conceptually you might have two chips
>> that are otherwise identical but one has a readable temp channel, the other
>> doesn't.  Userspace that is interested only in events won't care about
>> this difference.  Also we want to report what the conditions are as if it were
>> a channel we could read.  We want to know at what temperature this occurs.
> 
> Ok, what should a read on such a channel return, an error value or just an
> dummy value?
Definitely error. We might need some magic to stop the channel showing up
in scan_elements if the chip uses buffering.  Also, if I recall, the magic
channel number -1 (as used for timestamps) stops it having a read attribute
in the first place (in place for timestamps).

> 
> 
>> [...]
>>>
>>> My idea for supporting channel-less events is to add a event_mask to struct
>>> iio_info, which would be used just like a channels event_mask, but there
>>> would be no index for the sysfs attributes and for events we would set the
>>> event number to 0xffff.
>> Could you give more examples?  The temp one to my mind definitely needs a
>> channel, perhaps others do not?  I am not against in principal but not
>> yet certain exactly when this would make sense...
> 
> over-temperature is the only one i've seen so far. but other could be
> under-current or voltage for the whole chip.
There I'd also create a bonus voltage / current channel.  Need these particular
ones to map well because we'll probably have hwmon based in kernel users for them.


^ permalink raw reply

* Re: how stable are snapshots at the block level?
From: Stephane CHAZELAS @ 2011-10-24 15:08 UTC (permalink / raw)
  To: linux-btrfs
In-Reply-To: <000001cc9255$2b34fc70$819ef550$@nedharvey.com>

2011-10-24, 09:59(-04), Edward Ned Harvey:
[...]
> If you are reading the raw device underneath btrfs, you are
> not getting the benefit of the filesystem checksumming.  If
> you encounter an undetected read/write error, it will silently
> pass.  Your data will be corrupted, you'll never know about it
> until you see the side-effects (whatever they may be).
[...]

I don't follow you here. If you're cloning a device holding a
btrfs FS, you'll clone the checksums as well. If there were
errors, they will be detected on the cloned FS as well?

> There is never a situation where block level copies have any
> advantage over something like btrfs send.  Except perhaps
> forensics or espionage.  But in terms of fast efficient
> reliable backups, btrfs send has every advantage and no
> disadvantage compared to block level copy.

$ btrfs send
ERROR: unknown command 'send'
Usage:
[...]

(from 2011-10-12 integration branch). Am I missing something?

> There are many situations where btrfs send has an advantage
> over both block level and file level copies.  It instantly
> knows all the relevant disk blocks to send, it preserves every
> property, it's agnostic about filesystem size or layout on
> either sending or receiving end, you have the option to create
> different configurations on each side, including compression
> etc.  And so on.
[...]

That sounds like "zfs send", I didn't know btrfs had it yet.

My understanding was that to clone/backup a btrfs FS, you could
only clone the block devices or use the "device add" + "device
del" trick with some extra copy-on-write (LVM, nbd) layer.

-- 
Stephane


^ permalink raw reply

* [PATCH v5 3/7] arm: perf: support device with other non-irq resources
From: Will Deacon @ 2011-10-24 15:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1319467559-5518-4-git-send-email-ming.lei@canonical.com>

Hi Ming Lei,

On Mon, Oct 24, 2011 at 03:45:55PM +0100, ming.lei at canonical.com wrote:
> From: Ming Lei <ming.lei@canonical.com>
> 
> omap4 may create device via hwmod, which can create resources
> automatically, so may include some non-irq resources.
> 
> This patch supports device with other non-irq resources.

I'd rather not do this in the Perf code since we're essentially dealing with
an artifact of the hwmod -> platform_device conversion.

> Signed-off-by: Ming Lei <ming.lei@canonical.com>
> ---
>  arch/arm/kernel/perf_event.c |    5 +++--
>  arch/arm/kernel/pmu.c        |   12 ++++++++++--
>  2 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
> index f367780..d91dba2 100644
> --- a/arch/arm/kernel/perf_event.c
> +++ b/arch/arm/kernel/perf_event.c
> @@ -19,6 +19,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/spinlock.h>
>  #include <linux/uaccess.h>
> +#include <linux/cpumask.h>
>  
>  #include <asm/cputype.h>
>  #include <asm/irq.h>
> @@ -414,7 +415,7 @@ armpmu_reserve_hardware(void)
>  		return -ENODEV;
>  	}
>  
> -	for (i = 0; i < pmu_device->num_resources; ++i) {
> +	for (i = 0; i < nr_cpu_ids; ++i) {
>  		irq = platform_get_irq(pmu_device, i);
>  		if (irq < 0)
>  			continue;

Hmm, I actually changed this code recently. Take a look:

https://github.com/wdeacon/linux-wd/blob/perf/system-pmus/arch/arm/kernel/perf_event.c

This should all be in for 3.2-rc1, so you can rebase then. If you still have
hwmod issues, please solve them outside of perf_event.c

> diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
> index c53474f..0e9c908 100644
> --- a/arch/arm/kernel/pmu.c
> +++ b/arch/arm/kernel/pmu.c
> @@ -19,6 +19,7 @@
>  #include <linux/module.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
> +#include <linux/cpumask.h>

'fraid I've changed this file too!

https://github.com/wdeacon/linux-wd/blob/perf/system-pmus/arch/arm/kernel/pmu.c

Will

^ permalink raw reply

* Re: [PATCH v5 3/7] arm: perf: support device with other non-irq resources
From: Will Deacon @ 2011-10-24 15:08 UTC (permalink / raw)
  To: ming.lei@canonical.com
  Cc: paul@pwsan.com, linux@arm.linux.org.uk, tony@atomide.com,
	khilman@deeprootsystems.com, linux-omap@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <1319467559-5518-4-git-send-email-ming.lei@canonical.com>

Hi Ming Lei,

On Mon, Oct 24, 2011 at 03:45:55PM +0100, ming.lei@canonical.com wrote:
> From: Ming Lei <ming.lei@canonical.com>
> 
> omap4 may create device via hwmod, which can create resources
> automatically, so may include some non-irq resources.
> 
> This patch supports device with other non-irq resources.

I'd rather not do this in the Perf code since we're essentially dealing with
an artifact of the hwmod -> platform_device conversion.

> Signed-off-by: Ming Lei <ming.lei@canonical.com>
> ---
>  arch/arm/kernel/perf_event.c |    5 +++--
>  arch/arm/kernel/pmu.c        |   12 ++++++++++--
>  2 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
> index f367780..d91dba2 100644
> --- a/arch/arm/kernel/perf_event.c
> +++ b/arch/arm/kernel/perf_event.c
> @@ -19,6 +19,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/spinlock.h>
>  #include <linux/uaccess.h>
> +#include <linux/cpumask.h>
>  
>  #include <asm/cputype.h>
>  #include <asm/irq.h>
> @@ -414,7 +415,7 @@ armpmu_reserve_hardware(void)
>  		return -ENODEV;
>  	}
>  
> -	for (i = 0; i < pmu_device->num_resources; ++i) {
> +	for (i = 0; i < nr_cpu_ids; ++i) {
>  		irq = platform_get_irq(pmu_device, i);
>  		if (irq < 0)
>  			continue;

Hmm, I actually changed this code recently. Take a look:

https://github.com/wdeacon/linux-wd/blob/perf/system-pmus/arch/arm/kernel/perf_event.c

This should all be in for 3.2-rc1, so you can rebase then. If you still have
hwmod issues, please solve them outside of perf_event.c

> diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
> index c53474f..0e9c908 100644
> --- a/arch/arm/kernel/pmu.c
> +++ b/arch/arm/kernel/pmu.c
> @@ -19,6 +19,7 @@
>  #include <linux/module.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
> +#include <linux/cpumask.h>

'fraid I've changed this file too!

https://github.com/wdeacon/linux-wd/blob/perf/system-pmus/arch/arm/kernel/pmu.c

Will

^ permalink raw reply

* Re: [PATCH 1/2] LSM: Do not apply mmap_min_addr check to PROT_NONE mappings
From: Eric Paris @ 2011-10-24 15:07 UTC (permalink / raw)
  To: Roland McGrath
  Cc: Linus Torvalds, Andrew Morton, James Morris, Stephen Smalley,
	selinux, John Johansen, linux-security-module, linux-kernel
In-Reply-To: <20111023185243.EFE2F2C08F@topped-with-meat.com>

On Sun, 2011-10-23 at 11:52 -0700, Roland McGrath wrote:

> > But that's no reason for the kernel to *allow* the mapping.
> 
> I don't have a problem with that.

I feel like, and it's just a very vague feeling, that the PROT bits
didn't matter to the kernel.  It would still happily execute stuff on
page 0 even without PROT_EXEC at some point in the past.  I'm probably
totally off base, and I could test it, but I sort of feel like I
remember something like that....

If that's the case, NULL pointer kernel bugs won't be caught if they
happen while these are mapped by your program...


^ permalink raw reply

* Re: [PATCH 1/2] LSM: Do not apply mmap_min_addr check to PROT_NONE mappings
From: Eric Paris @ 2011-10-24 15:07 UTC (permalink / raw)
  To: Roland McGrath
  Cc: Linus Torvalds, Andrew Morton, James Morris, Stephen Smalley,
	selinux, John Johansen, linux-security-module, linux-kernel
In-Reply-To: <20111023185243.EFE2F2C08F@topped-with-meat.com>

On Sun, 2011-10-23 at 11:52 -0700, Roland McGrath wrote:

> > But that's no reason for the kernel to *allow* the mapping.
> 
> I don't have a problem with that.

I feel like, and it's just a very vague feeling, that the PROT bits
didn't matter to the kernel.  It would still happily execute stuff on
page 0 even without PROT_EXEC at some point in the past.  I'm probably
totally off base, and I could test it, but I sort of feel like I
remember something like that....

If that's the case, NULL pointer kernel bugs won't be caught if they
happen while these are mapped by your program...


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply

* Re: [Qemu-devel] [PATCH 29/35] scsi-disk: remove cluster_size
From: Kevin Wolf @ 2011-10-24 15:10 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel
In-Reply-To: <1318503845-11473-30-git-send-email-pbonzini@redhat.com>

Am 13.10.2011 13:03, schrieb Paolo Bonzini:
> This field is redundant, and its presence makes it more complicated
> to share reqops between the upcoming scsi-block and scsi-generic.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/scsi-disk.c |   45 ++++++++++++++++++++++-----------------------
>  1 files changed, 22 insertions(+), 23 deletions(-)
> 
> diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
> index 5e3ef51..7f2f67f 100644
> --- a/hw/scsi-disk.c
> +++ b/hw/scsi-disk.c
> @@ -65,9 +65,6 @@ typedef struct SCSIDiskReq {
>  struct SCSIDiskState
>  {
>      SCSIDevice qdev;
> -    /* The qemu block layer uses a fixed 512 byte sector size.
> -       This is the number of 512 byte blocks in a single scsi sector.  */
> -    int cluster_size;
>      uint32_t removable;
>      uint64_t max_lba;
>      bool media_changed;
> @@ -862,7 +859,7 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
>          bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
>          p[4] = heads & 0xff;
>          p[5] = secs & 0xff;
> -        p[6] = s->cluster_size * 2;
> +        p[6] = s->qdev.blocksize >> 8;
>          p[8] = (cylinders >> 8) & 0xff;
>          p[9] = cylinders & 0xff;
>          /* Write precomp start cylinder, disabled */
> @@ -991,7 +988,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
>          } else { /* MODE_SENSE_10 */
>              outbuf[7] = 8; /* Block descriptor length  */
>          }
> -        nb_sectors /= s->cluster_size;
> +        nb_sectors /= (s->qdev.blocksize / 512);
>          if (nb_sectors > 0xffffff)
>              nb_sectors = 0;
>          p[0] = 0; /* media density code */
> @@ -1000,7 +997,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
>          p[3] = nb_sectors & 0xff;
>          p[4] = 0; /* reserved */
>          p[5] = 0; /* bytes 5-7 are the sector size in bytes */
> -        p[6] = s->cluster_size * 2;
> +        p[6] = s->qdev.blocksize >> 8;
>          p[7] = 0;
>          p += 8;
>      }
> @@ -1050,7 +1047,7 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
>      start_track = req->cmd.buf[6];
>      bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
>      DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
> -    nb_sectors /= s->cluster_size;
> +    nb_sectors /= s->qdev.blocksize / 512;
>      switch (format) {
>      case 0:
>          toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
> @@ -1176,7 +1173,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
>          if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) {
>              goto illegal_request;
>          }
> -        nb_sectors /= s->cluster_size;
> +        nb_sectors /= s->qdev.blocksize / 512;
>          /* Returned value is the address of the last sector.  */
>          nb_sectors--;
>          /* Remember the new size for read/write sanity checking. */
> @@ -1190,7 +1187,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
>          outbuf[3] = nb_sectors & 0xff;
>          outbuf[4] = 0;
>          outbuf[5] = 0;
> -        outbuf[6] = s->cluster_size * 2;
> +        outbuf[6] = s->qdev.blocksize >> 8;
>          outbuf[7] = 0;
>          buflen = 8;
>          break;
> @@ -1226,7 +1223,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
>              if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) {
>                  goto illegal_request;
>              }
> -            nb_sectors /= s->cluster_size;
> +            nb_sectors /= s->qdev.blocksize / 512;
>              /* Returned value is the address of the last sector.  */
>              nb_sectors--;
>              /* Remember the new size for read/write sanity checking. */
> @@ -1241,7 +1238,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
>              outbuf[7] = nb_sectors & 0xff;
>              outbuf[8] = 0;
>              outbuf[9] = 0;
> -            outbuf[10] = s->cluster_size * 2;
> +            outbuf[10] = s->qdev.blocksize >> 8;
>              outbuf[11] = 0;
>              outbuf[12] = 0;
>              outbuf[13] = get_physical_block_exp(&s->qdev.conf);
> @@ -1349,8 +1346,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
>          DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
>          if (r->req.cmd.lba > s->max_lba)
>              goto illegal_lba;
> -        r->sector = r->req.cmd.lba * s->cluster_size;
> -        r->sector_count = len * s->cluster_size;
> +        r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
> +        r->sector_count = len * (s->qdev.blocksize / 512);
>          break;
>      case WRITE_6:
>      case WRITE_10:
> @@ -1365,8 +1362,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
>                  r->req.cmd.lba, len);
>          if (r->req.cmd.lba > s->max_lba)
>              goto illegal_lba;
> -        r->sector = r->req.cmd.lba * s->cluster_size;
> -        r->sector_count = len * s->cluster_size;
> +        r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
> +        r->sector_count = len * (s->qdev.blocksize / 512);
>          break;
>      case MODE_SELECT:
>          DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
> @@ -1409,8 +1406,9 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
>              goto fail;
>          }
>  
> -        rc = bdrv_discard(s->qdev.conf.bs, r->req.cmd.lba * s->cluster_size,
> -                          len * s->cluster_size);
> +        rc = bdrv_discard(s->qdev.conf.bs,
> +                          r->req.cmd.lba * (s->qdev.blocksize / 512),
> +                          len * (s->qdev.blocksize / 512));
>          if (rc < 0) {
>              /* XXX: better error code ?*/
>              goto fail;
> @@ -1450,12 +1448,14 @@ static void scsi_disk_reset(DeviceState *dev)
>  
>      scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
>  
> -    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
> -    nb_sectors /= s->cluster_size;
> -    if (nb_sectors) {
> -        nb_sectors--;
> +    if (s->qdev.blocksize) {

When would it be 0? And wouldn't we crash with a zero blocksize anyway?

Kevin

^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.