Re: [PATCH 1/2] net: ethernet: ti: cpts: convert to use kthread_worker

2017-07-21 Thread Richard Cochran
On Fri, Jul 21, 2017 at 06:49:42PM -0500, Grygorii Strashko wrote:
> There could be significant delay in CPTS work schedule under high system
> load and on -RT which could cause CPTS misbehavior due to internal counter
> overflow. Usage of own kthread_worker allows to avoid such kind of issues
> and makes it possible to tune priority of CPTS kthread_worker thread on -RT
> (thread name "cpts").

I have also seen excessive delays in the time stamp work from the
dp83640 under certain loads.  Can we please implement this time stamp
kthread_worker in the PHC subsystem?  That way, the facility can be
used by other drivers without code duplication.

Thanks,
Richard


Re: [PATCH 1/2] net: ethernet: ti: cpts: convert to use kthread_worker

2017-07-21 Thread Richard Cochran
On Fri, Jul 21, 2017 at 06:49:42PM -0500, Grygorii Strashko wrote:
> There could be significant delay in CPTS work schedule under high system
> load and on -RT which could cause CPTS misbehavior due to internal counter
> overflow. Usage of own kthread_worker allows to avoid such kind of issues
> and makes it possible to tune priority of CPTS kthread_worker thread on -RT
> (thread name "cpts").

I have also seen excessive delays in the time stamp work from the
dp83640 under certain loads.  Can we please implement this time stamp
kthread_worker in the PHC subsystem?  That way, the facility can be
used by other drivers without code duplication.

Thanks,
Richard


Re: [PATCH v7 2/3] PCI: Enable PCIe Relaxed Ordering if supported

2017-07-21 Thread Ding Tianhong
Hi Sinan, Bjorn:

On 2017/7/14 21:54, Sinan Kaya wrote:
> On 7/13/2017 9:26 PM, Ding Tianhong wrote:
>> There is no code to enable the PCIe Relaxed Ordering bit in the 
>> configuration space,
>> it is only be enable by default according to the PCIe Standard 
>> Specification, what we
>> do is to distinguish the RC problematic platform and clear the Relaxed 
>> Ordering bit
>> to tell the PCIe EP don't send any TLPs with Relaxed Ordering Attributes to 
>> the Root
>> Complex.
> 
> Maybe, you should change the patch commit as 
> "Disable PCIe Relaxed Ordering if not supported"...

I agree that to use the new commit title as your suggested, thanks. :)

@Bjorn do you want me to spawn a new patchset with the new commit title
and the Reviewed-by from Casey on the patch 3, or maybe you could pick this
up and modify it own ? thanks.

Ding

> 



Re: [PATCH v7 2/3] PCI: Enable PCIe Relaxed Ordering if supported

2017-07-21 Thread Ding Tianhong
Hi Sinan, Bjorn:

On 2017/7/14 21:54, Sinan Kaya wrote:
> On 7/13/2017 9:26 PM, Ding Tianhong wrote:
>> There is no code to enable the PCIe Relaxed Ordering bit in the 
>> configuration space,
>> it is only be enable by default according to the PCIe Standard 
>> Specification, what we
>> do is to distinguish the RC problematic platform and clear the Relaxed 
>> Ordering bit
>> to tell the PCIe EP don't send any TLPs with Relaxed Ordering Attributes to 
>> the Root
>> Complex.
> 
> Maybe, you should change the patch commit as 
> "Disable PCIe Relaxed Ordering if not supported"...

I agree that to use the new commit title as your suggested, thanks. :)

@Bjorn do you want me to spawn a new patchset with the new commit title
and the Reviewed-by from Casey on the patch 3, or maybe you could pick this
up and modify it own ? thanks.

Ding

> 



[PATCH v2] irqchip/gic-v3-its: Allow GIC ITS number more than MAX_NUMNODES

2017-07-21 Thread Hanjun Guo
From: Hanjun Guo 

When running 4.13-rc1 on top of D05, I got the boot log:

[0.00] SRAT: PXM 0 -> ITS 0 -> Node 0
[0.00] SRAT: PXM 0 -> ITS 1 -> Node 0
[0.00] SRAT: PXM 0 -> ITS 2 -> Node 0
[0.00] SRAT: PXM 1 -> ITS 3 -> Node 1
[0.00] SRAT: ITS affinity exceeding max count[4]

This is wrong on D05 as we have 8 ITSes with 4 NUMA nodes.

So dynamically alloc the memory needed instead of using
its_srat_maps[MAX_NUMNODES], which count the number of
ITS entry(ies) in SRAT and alloc its_srat_maps as needed,
then build the mapping of numa node to ITS ID. Of course,
its_srat_maps will be freed after ITS probing because
we don't need that after boot.

After doing this, I got what I wanted:

[0.00] SRAT: PXM 0 -> ITS 0 -> Node 0
[0.00] SRAT: PXM 0 -> ITS 1 -> Node 0
[0.00] SRAT: PXM 0 -> ITS 2 -> Node 0
[0.00] SRAT: PXM 1 -> ITS 3 -> Node 1
[0.00] SRAT: PXM 2 -> ITS 4 -> Node 2
[0.00] SRAT: PXM 2 -> ITS 5 -> Node 2
[0.00] SRAT: PXM 2 -> ITS 6 -> Node 2
[0.00] SRAT: PXM 3 -> ITS 7 -> Node 3

Fixes: dbd2b8267233 ("irqchip/gic-v3-its: Add ACPI NUMA node mapping")
Signed-off-by: Hanjun Guo 
Cc: Ganapatrao Kulkarni 
Cc: Lorenzo Pieralisi 
Cc: Marc Zyngier 
---

v1->v2:
  - Add NULL check in acpi_get_its_numa_node() for no ITS affinity case;
  - Free the its_srat_maps after ITS probing.

 drivers/irqchip/irq-gic-v3-its.c | 39 ---
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 3ccdf76..1d692aa 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1847,13 +1847,16 @@ struct its_srat_map {
u32 its_id;
 };
 
-static struct its_srat_map its_srat_maps[MAX_NUMNODES] __initdata;
+static struct its_srat_map *its_srat_maps __initdata;
 static int its_in_srat __initdata;
 
 static int __init acpi_get_its_numa_node(u32 its_id)
 {
int i;
 
+   if (!its_srat_maps)
+   return NUMA_NO_NODE;
+
for (i = 0; i < its_in_srat; i++) {
if (its_id == its_srat_maps[i].its_id)
return its_srat_maps[i].numa_node;
@@ -1861,6 +1864,12 @@ static int __init acpi_get_its_numa_node(u32 its_id)
return NUMA_NO_NODE;
 }
 
+static int __init gic_acpi_match_srat_its(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+   return 0;
+}
+
 static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header,
 const unsigned long end)
 {
@@ -1877,12 +1886,6 @@ static int __init gic_acpi_parse_srat_its(struct 
acpi_subtable_header *header,
return -EINVAL;
}
 
-   if (its_in_srat >= MAX_NUMNODES) {
-   pr_err("SRAT: ITS affinity exceeding max count[%d]\n",
-   MAX_NUMNODES);
-   return -EINVAL;
-   }
-
node = acpi_map_pxm_to_node(its_affinity->proximity_domain);
 
if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
@@ -1901,14 +1904,35 @@ static int __init gic_acpi_parse_srat_its(struct 
acpi_subtable_header *header,
 
 static void __init acpi_table_parse_srat_its(void)
 {
+   int count;
+
+   count = acpi_table_parse_entries(ACPI_SIG_SRAT,
+   sizeof(struct acpi_table_srat),
+   ACPI_SRAT_TYPE_GIC_ITS_AFFINITY,
+   gic_acpi_match_srat_its, 0);
+   if (count <= 0)
+   return;
+
+   its_srat_maps = kmalloc(count * sizeof(struct its_srat_map),
+   GFP_KERNEL);
+   if (!its_srat_maps)
+   return;
+
acpi_table_parse_entries(ACPI_SIG_SRAT,
sizeof(struct acpi_table_srat),
ACPI_SRAT_TYPE_GIC_ITS_AFFINITY,
gic_acpi_parse_srat_its, 0);
 }
+
+/* free the its_srat_maps after ITS probing */
+static void __init acpi_its_srat_maps_free(void)
+{
+   kfree(its_srat_maps);
+}
 #else
 static void __init acpi_table_parse_srat_its(void) { }
 static int __init acpi_get_its_numa_node(u32 its_id) { return NUMA_NO_NODE; }
+static void __init acpi_its_srat_maps_free(void) { }
 #endif
 
 static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
@@ -1955,6 +1979,7 @@ static void __init its_acpi_probe(void)
acpi_table_parse_srat_its();
acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
  gic_acpi_parse_madt_its, 0);
+   acpi_its_srat_maps_free();
 }
 #else
 static void __init its_acpi_probe(void) { }
-- 
1.7.12.4



[PATCH v2] irqchip/gic-v3-its: Allow GIC ITS number more than MAX_NUMNODES

2017-07-21 Thread Hanjun Guo
From: Hanjun Guo 

When running 4.13-rc1 on top of D05, I got the boot log:

[0.00] SRAT: PXM 0 -> ITS 0 -> Node 0
[0.00] SRAT: PXM 0 -> ITS 1 -> Node 0
[0.00] SRAT: PXM 0 -> ITS 2 -> Node 0
[0.00] SRAT: PXM 1 -> ITS 3 -> Node 1
[0.00] SRAT: ITS affinity exceeding max count[4]

This is wrong on D05 as we have 8 ITSes with 4 NUMA nodes.

So dynamically alloc the memory needed instead of using
its_srat_maps[MAX_NUMNODES], which count the number of
ITS entry(ies) in SRAT and alloc its_srat_maps as needed,
then build the mapping of numa node to ITS ID. Of course,
its_srat_maps will be freed after ITS probing because
we don't need that after boot.

After doing this, I got what I wanted:

[0.00] SRAT: PXM 0 -> ITS 0 -> Node 0
[0.00] SRAT: PXM 0 -> ITS 1 -> Node 0
[0.00] SRAT: PXM 0 -> ITS 2 -> Node 0
[0.00] SRAT: PXM 1 -> ITS 3 -> Node 1
[0.00] SRAT: PXM 2 -> ITS 4 -> Node 2
[0.00] SRAT: PXM 2 -> ITS 5 -> Node 2
[0.00] SRAT: PXM 2 -> ITS 6 -> Node 2
[0.00] SRAT: PXM 3 -> ITS 7 -> Node 3

Fixes: dbd2b8267233 ("irqchip/gic-v3-its: Add ACPI NUMA node mapping")
Signed-off-by: Hanjun Guo 
Cc: Ganapatrao Kulkarni 
Cc: Lorenzo Pieralisi 
Cc: Marc Zyngier 
---

v1->v2:
  - Add NULL check in acpi_get_its_numa_node() for no ITS affinity case;
  - Free the its_srat_maps after ITS probing.

 drivers/irqchip/irq-gic-v3-its.c | 39 ---
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 3ccdf76..1d692aa 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1847,13 +1847,16 @@ struct its_srat_map {
u32 its_id;
 };
 
-static struct its_srat_map its_srat_maps[MAX_NUMNODES] __initdata;
+static struct its_srat_map *its_srat_maps __initdata;
 static int its_in_srat __initdata;
 
 static int __init acpi_get_its_numa_node(u32 its_id)
 {
int i;
 
+   if (!its_srat_maps)
+   return NUMA_NO_NODE;
+
for (i = 0; i < its_in_srat; i++) {
if (its_id == its_srat_maps[i].its_id)
return its_srat_maps[i].numa_node;
@@ -1861,6 +1864,12 @@ static int __init acpi_get_its_numa_node(u32 its_id)
return NUMA_NO_NODE;
 }
 
+static int __init gic_acpi_match_srat_its(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+   return 0;
+}
+
 static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header,
 const unsigned long end)
 {
@@ -1877,12 +1886,6 @@ static int __init gic_acpi_parse_srat_its(struct 
acpi_subtable_header *header,
return -EINVAL;
}
 
-   if (its_in_srat >= MAX_NUMNODES) {
-   pr_err("SRAT: ITS affinity exceeding max count[%d]\n",
-   MAX_NUMNODES);
-   return -EINVAL;
-   }
-
node = acpi_map_pxm_to_node(its_affinity->proximity_domain);
 
if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
@@ -1901,14 +1904,35 @@ static int __init gic_acpi_parse_srat_its(struct 
acpi_subtable_header *header,
 
 static void __init acpi_table_parse_srat_its(void)
 {
+   int count;
+
+   count = acpi_table_parse_entries(ACPI_SIG_SRAT,
+   sizeof(struct acpi_table_srat),
+   ACPI_SRAT_TYPE_GIC_ITS_AFFINITY,
+   gic_acpi_match_srat_its, 0);
+   if (count <= 0)
+   return;
+
+   its_srat_maps = kmalloc(count * sizeof(struct its_srat_map),
+   GFP_KERNEL);
+   if (!its_srat_maps)
+   return;
+
acpi_table_parse_entries(ACPI_SIG_SRAT,
sizeof(struct acpi_table_srat),
ACPI_SRAT_TYPE_GIC_ITS_AFFINITY,
gic_acpi_parse_srat_its, 0);
 }
+
+/* free the its_srat_maps after ITS probing */
+static void __init acpi_its_srat_maps_free(void)
+{
+   kfree(its_srat_maps);
+}
 #else
 static void __init acpi_table_parse_srat_its(void) { }
 static int __init acpi_get_its_numa_node(u32 its_id) { return NUMA_NO_NODE; }
+static void __init acpi_its_srat_maps_free(void) { }
 #endif
 
 static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
@@ -1955,6 +1979,7 @@ static void __init its_acpi_probe(void)
acpi_table_parse_srat_its();
acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
  gic_acpi_parse_madt_its, 0);
+   acpi_its_srat_maps_free();
 }
 #else
 static void __init its_acpi_probe(void) { }
-- 
1.7.12.4



Re: [PATCH] irqchip/gic-v3-its: Allow GIC ITS number more than MAX_NUMNODES

2017-07-21 Thread Hanjun Guo
On 2017/7/21 19:42, Ganapatrao Kulkarni wrote:
> Hi Hanjun,
>
>
> On Fri, Jul 21, 2017 at 4:50 PM, Marc Zyngier  wrote:
>> On 21/07/17 11:06, Hanjun Guo wrote:
>>> On 2017/7/21 17:51, Hanjun Guo wrote:
 From: Hanjun Guo 

 When running 4.13-rc1 on top of D05, I got the boot log:

 [0.00] SRAT: PXM 0 -> ITS 0 -> Node 0
 [0.00] SRAT: PXM 0 -> ITS 1 -> Node 0
 [0.00] SRAT: PXM 0 -> ITS 2 -> Node 0
 [0.00] SRAT: PXM 1 -> ITS 3 -> Node 1
 [0.00] SRAT: ITS affinity exceeding max count[4]

 This is wrong on D05 as we have 8 ITSes with 4 NUMA nodes.
> Used static array to keep it simple.  we can have either dynamic array
> or increase static array size (which is in init data) to a larger
> number.
> We may have to go for dynamic array to be more sane. You can refer my
> v2 patch [1], which was doing dynamic allocation and avoids
> 2 calls to acpi parser as done in this patch.
>
> [1] https://patchwork.kernel.org/patch/9798659/

Hmm, although scanning the SRAT twice is bad, it will keep the
code simple, and no need to alloc the memory every time when we
find a ITS affinity entry, you need to free that memory when
ITS probing is done.

I will post a patch later, please take a look if it's ok to you :)

Thanks
Hanjun



Re: [PATCH] irqchip/gic-v3-its: Allow GIC ITS number more than MAX_NUMNODES

2017-07-21 Thread Hanjun Guo
On 2017/7/21 19:42, Ganapatrao Kulkarni wrote:
> Hi Hanjun,
>
>
> On Fri, Jul 21, 2017 at 4:50 PM, Marc Zyngier  wrote:
>> On 21/07/17 11:06, Hanjun Guo wrote:
>>> On 2017/7/21 17:51, Hanjun Guo wrote:
 From: Hanjun Guo 

 When running 4.13-rc1 on top of D05, I got the boot log:

 [0.00] SRAT: PXM 0 -> ITS 0 -> Node 0
 [0.00] SRAT: PXM 0 -> ITS 1 -> Node 0
 [0.00] SRAT: PXM 0 -> ITS 2 -> Node 0
 [0.00] SRAT: PXM 1 -> ITS 3 -> Node 1
 [0.00] SRAT: ITS affinity exceeding max count[4]

 This is wrong on D05 as we have 8 ITSes with 4 NUMA nodes.
> Used static array to keep it simple.  we can have either dynamic array
> or increase static array size (which is in init data) to a larger
> number.
> We may have to go for dynamic array to be more sane. You can refer my
> v2 patch [1], which was doing dynamic allocation and avoids
> 2 calls to acpi parser as done in this patch.
>
> [1] https://patchwork.kernel.org/patch/9798659/

Hmm, although scanning the SRAT twice is bad, it will keep the
code simple, and no need to alloc the memory every time when we
find a ITS affinity entry, you need to free that memory when
ITS probing is done.

I will post a patch later, please take a look if it's ok to you :)

Thanks
Hanjun



[PATCH 3/3] staging: pi433: - style fix, space at start of line

2017-07-21 Thread Derek Robson
Fixed checkpatch errors of "please, no spaces at the start of a line"

Signed-off-by: Derek Robson 
---
 drivers/staging/pi433/rf69.c  |   4 +-
 drivers/staging/pi433/rf69_enum.h | 206 +++---
 2 files changed, 105 insertions(+), 105 deletions(-)

diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c
index d931437f0b6a..f450bbf3fbbc 100644
--- a/drivers/staging/pi433/rf69.c
+++ b/drivers/staging/pi433/rf69.c
@@ -440,8 +440,8 @@ int rf69_set_bandwidth_intern(struct spi_device *spi, u8 
reg, enum mantisse mant
// check value for mantisse and exponent
if (exponent > 7)   INVALID_PARAM;
if ( (mantisse!=mantisse16) &&
-(mantisse!=mantisse20) &&
- (mantisse!=mantisse24) ) INVALID_PARAM;
+   (mantisse!=mantisse20) &&
+   (mantisse!=mantisse24) ) INVALID_PARAM;
 
// read old value
newValue = READ_REG(reg);
diff --git a/drivers/staging/pi433/rf69_enum.h 
b/drivers/staging/pi433/rf69_enum.h
index fbfb59bd3f3d..635629415e63 100644
--- a/drivers/staging/pi433/rf69_enum.h
+++ b/drivers/staging/pi433/rf69_enum.h
@@ -20,181 +20,181 @@
 
 enum optionOnOff
 {
-optionOff,
-optionOn
+   optionOff,
+   optionOn
 };
 
 enum mode
 {
-mode_sleep,
-standby,
-synthesizer,
-transmit,
-receive
+   mode_sleep,
+   standby,
+   synthesizer,
+   transmit,
+   receive
 };
 
 enum dataMode
 {
-packet,
-continuous,
-continuousNoSync
+   packet,
+   continuous,
+   continuousNoSync
 };
 
 enum modulation
 {
-OOK,
-FSK
+   OOK,
+   FSK
 };
 
 enum modShaping
 {
-shapingOff,
-shaping1_0,
-shaping0_5,
-shaping0_3,
-shapingBR,
-shaping2BR
+   shapingOff,
+   shaping1_0,
+   shaping0_5,
+   shaping0_3,
+   shapingBR,
+   shaping2BR
 };
 
 enum paRamp
 {
-ramp3400,
-ramp2000,
-ramp1000,
-ramp500,
-ramp250,
-ramp125,
-ramp100,
-ramp62,
-ramp50,
-ramp40,
-ramp31,
-ramp25,
-ramp20,
-ramp15,
-ramp12,
-ramp10
+   ramp3400,
+   ramp2000,
+   ramp1000,
+   ramp500,
+   ramp250,
+   ramp125,
+   ramp100,
+   ramp62,
+   ramp50,
+   ramp40,
+   ramp31,
+   ramp25,
+   ramp20,
+   ramp15,
+   ramp12,
+   ramp10
 };
 
 enum antennaImpedance
 {
-fiftyOhm,
-twohundretOhm
+   fiftyOhm,
+   twohundretOhm
 };
 
 enum lnaGain
 {
-automatic,
-max,
-maxMinus6,
-maxMinus12,
-maxMinus24,
-maxMinus36,
-maxMinus48,
-undefined
+   automatic,
+   max,
+   maxMinus6,
+   maxMinus12,
+   maxMinus24,
+   maxMinus36,
+   maxMinus48,
+   undefined
 };
 
 enum dccPercent
 {
-dcc16Percent,
-dcc8Percent,
-dcc4Percent,
-dcc2Percent,
-dcc1Percent,
-dcc0_5Percent,
-dcc0_25Percent,
-dcc0_125Percent
+   dcc16Percent,
+   dcc8Percent,
+   dcc4Percent,
+   dcc2Percent,
+   dcc1Percent,
+   dcc0_5Percent,
+   dcc0_25Percent,
+   dcc0_125Percent
 };
 
 enum mantisse
 {
-mantisse16,
-mantisse20,
-mantisse24
+   mantisse16,
+   mantisse20,
+   mantisse24
 };
 
 enum thresholdType
 {
-fixed,
-peak,
-average
+   fixed,
+   peak,
+   average
 };
 
 enum thresholdStep
 {
-step_0_5db,
-step_1_0db,
-step_1_5db,
-step_2_0db,
-step_3_0db,
-step_4_0db,
-step_5_0db,
-step_6_0db
+   step_0_5db,
+   step_1_0db,
+   step_1_5db,
+   step_2_0db,
+   step_3_0db,
+   step_4_0db,
+   step_5_0db,
+   step_6_0db
 };
 
 enum thresholdDecrement
 {
-dec_every8th,
-dec_every4th,
-dec_every2nd,
-dec_once,
-dec_twice,
-dec_4times,
-dec_8times,
-dec_16times
+   dec_every8th,
+   dec_every4th,
+   dec_every2nd,
+   dec_once,
+   dec_twice,
+   dec_4times,
+   dec_8times,
+   dec_16times
 };
 
 enum flag
 {
-modeSwitchCompleted,
-readyToReceive,
-readyToSend,
-pllLocked,
-rssiExceededThreshold,
-timeout,
-automode,
-syncAddressMatch,
-fifoFull,
-//fifoNotEmpty, collision with next enum; replaced by following enum...
-fifoEmpty,
-fifoLevelBelowThreshold,
-fifoOverrun,
-packetSent,
-payloadReady,
-crcOk,
-batteryLow
+   modeSwitchCompleted,
+   readyToReceive,
+   readyToSend,
+   pllLocked,
+   rssiExceededThreshold,
+   timeout,
+   automode,
+   syncAddressMatch,
+   fifoFull,
+   // fifoNotEmpty, collision with next enum; replaced by following enum...
+   fifoEmpty,
+   fifoLevelBelowThreshold,
+   fifoOverrun,
+   packetSent,
+   payloadReady,
+   crcOk,
+   batteryLow
 };
 
 enum fifoFillCondition
 {
-afterSyncInterrupt,
-always
+  

[PATCH 3/3] staging: pi433: - style fix, space at start of line

2017-07-21 Thread Derek Robson
Fixed checkpatch errors of "please, no spaces at the start of a line"

Signed-off-by: Derek Robson 
---
 drivers/staging/pi433/rf69.c  |   4 +-
 drivers/staging/pi433/rf69_enum.h | 206 +++---
 2 files changed, 105 insertions(+), 105 deletions(-)

diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c
index d931437f0b6a..f450bbf3fbbc 100644
--- a/drivers/staging/pi433/rf69.c
+++ b/drivers/staging/pi433/rf69.c
@@ -440,8 +440,8 @@ int rf69_set_bandwidth_intern(struct spi_device *spi, u8 
reg, enum mantisse mant
// check value for mantisse and exponent
if (exponent > 7)   INVALID_PARAM;
if ( (mantisse!=mantisse16) &&
-(mantisse!=mantisse20) &&
- (mantisse!=mantisse24) ) INVALID_PARAM;
+   (mantisse!=mantisse20) &&
+   (mantisse!=mantisse24) ) INVALID_PARAM;
 
// read old value
newValue = READ_REG(reg);
diff --git a/drivers/staging/pi433/rf69_enum.h 
b/drivers/staging/pi433/rf69_enum.h
index fbfb59bd3f3d..635629415e63 100644
--- a/drivers/staging/pi433/rf69_enum.h
+++ b/drivers/staging/pi433/rf69_enum.h
@@ -20,181 +20,181 @@
 
 enum optionOnOff
 {
-optionOff,
-optionOn
+   optionOff,
+   optionOn
 };
 
 enum mode
 {
-mode_sleep,
-standby,
-synthesizer,
-transmit,
-receive
+   mode_sleep,
+   standby,
+   synthesizer,
+   transmit,
+   receive
 };
 
 enum dataMode
 {
-packet,
-continuous,
-continuousNoSync
+   packet,
+   continuous,
+   continuousNoSync
 };
 
 enum modulation
 {
-OOK,
-FSK
+   OOK,
+   FSK
 };
 
 enum modShaping
 {
-shapingOff,
-shaping1_0,
-shaping0_5,
-shaping0_3,
-shapingBR,
-shaping2BR
+   shapingOff,
+   shaping1_0,
+   shaping0_5,
+   shaping0_3,
+   shapingBR,
+   shaping2BR
 };
 
 enum paRamp
 {
-ramp3400,
-ramp2000,
-ramp1000,
-ramp500,
-ramp250,
-ramp125,
-ramp100,
-ramp62,
-ramp50,
-ramp40,
-ramp31,
-ramp25,
-ramp20,
-ramp15,
-ramp12,
-ramp10
+   ramp3400,
+   ramp2000,
+   ramp1000,
+   ramp500,
+   ramp250,
+   ramp125,
+   ramp100,
+   ramp62,
+   ramp50,
+   ramp40,
+   ramp31,
+   ramp25,
+   ramp20,
+   ramp15,
+   ramp12,
+   ramp10
 };
 
 enum antennaImpedance
 {
-fiftyOhm,
-twohundretOhm
+   fiftyOhm,
+   twohundretOhm
 };
 
 enum lnaGain
 {
-automatic,
-max,
-maxMinus6,
-maxMinus12,
-maxMinus24,
-maxMinus36,
-maxMinus48,
-undefined
+   automatic,
+   max,
+   maxMinus6,
+   maxMinus12,
+   maxMinus24,
+   maxMinus36,
+   maxMinus48,
+   undefined
 };
 
 enum dccPercent
 {
-dcc16Percent,
-dcc8Percent,
-dcc4Percent,
-dcc2Percent,
-dcc1Percent,
-dcc0_5Percent,
-dcc0_25Percent,
-dcc0_125Percent
+   dcc16Percent,
+   dcc8Percent,
+   dcc4Percent,
+   dcc2Percent,
+   dcc1Percent,
+   dcc0_5Percent,
+   dcc0_25Percent,
+   dcc0_125Percent
 };
 
 enum mantisse
 {
-mantisse16,
-mantisse20,
-mantisse24
+   mantisse16,
+   mantisse20,
+   mantisse24
 };
 
 enum thresholdType
 {
-fixed,
-peak,
-average
+   fixed,
+   peak,
+   average
 };
 
 enum thresholdStep
 {
-step_0_5db,
-step_1_0db,
-step_1_5db,
-step_2_0db,
-step_3_0db,
-step_4_0db,
-step_5_0db,
-step_6_0db
+   step_0_5db,
+   step_1_0db,
+   step_1_5db,
+   step_2_0db,
+   step_3_0db,
+   step_4_0db,
+   step_5_0db,
+   step_6_0db
 };
 
 enum thresholdDecrement
 {
-dec_every8th,
-dec_every4th,
-dec_every2nd,
-dec_once,
-dec_twice,
-dec_4times,
-dec_8times,
-dec_16times
+   dec_every8th,
+   dec_every4th,
+   dec_every2nd,
+   dec_once,
+   dec_twice,
+   dec_4times,
+   dec_8times,
+   dec_16times
 };
 
 enum flag
 {
-modeSwitchCompleted,
-readyToReceive,
-readyToSend,
-pllLocked,
-rssiExceededThreshold,
-timeout,
-automode,
-syncAddressMatch,
-fifoFull,
-//fifoNotEmpty, collision with next enum; replaced by following enum...
-fifoEmpty,
-fifoLevelBelowThreshold,
-fifoOverrun,
-packetSent,
-payloadReady,
-crcOk,
-batteryLow
+   modeSwitchCompleted,
+   readyToReceive,
+   readyToSend,
+   pllLocked,
+   rssiExceededThreshold,
+   timeout,
+   automode,
+   syncAddressMatch,
+   fifoFull,
+   // fifoNotEmpty, collision with next enum; replaced by following enum...
+   fifoEmpty,
+   fifoLevelBelowThreshold,
+   fifoOverrun,
+   packetSent,
+   payloadReady,
+   crcOk,
+   batteryLow
 };
 
 enum fifoFillCondition
 {
-afterSyncInterrupt,
-always
+   

[PATCH 2/3] staging: pi433: - style fix, space before tabs

2017-07-21 Thread Derek Robson
Fixed checkpatch errors of "no space before tabs"

Signed-off-by: Derek Robson 
---
 drivers/staging/pi433/pi433_if.c | 12 ++--
 drivers/staging/pi433/pi433_if.h |  4 ++--
 drivers/staging/pi433/rf69.c |  8 
 drivers/staging/pi433/rf69.h |  6 +++---
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c
index 9cdebe93657c..b9e9292c01d9 100644
--- a/drivers/staging/pi433/pi433_if.c
+++ b/drivers/staging/pi433/pi433_if.c
@@ -190,12 +190,12 @@ rf69_set_rx_cfg(struct pi433_device *dev, struct 
pi433_rx_cfg *rx_cfg)
SET_CHECKED(rf69_set_frequency  (dev->spi, rx_cfg->frequency));
SET_CHECKED(rf69_set_bit_rate   (dev->spi, rx_cfg->bit_rate));
SET_CHECKED(rf69_set_modulation (dev->spi, rx_cfg->modulation));
-   SET_CHECKED(rf69_set_antenna_impedance   (dev->spi, 
rx_cfg->antenna_impedance));
-   SET_CHECKED(rf69_set_rssi_threshold  (dev->spi, 
rx_cfg->rssi_threshold));
-   SET_CHECKED(rf69_set_ook_threshold_dec   (dev->spi, 
rx_cfg->thresholdDecrement));
-   SET_CHECKED(rf69_set_bandwidth   (dev->spi, 
rx_cfg->bw_mantisse, rx_cfg->bw_exponent));
+   SET_CHECKED(rf69_set_antenna_impedance(dev->spi, 
rx_cfg->antenna_impedance));
+   SET_CHECKED(rf69_set_rssi_threshold(dev->spi, rx_cfg->rssi_threshold));
+   SET_CHECKED(rf69_set_ook_threshold_dec(dev->spi, 
rx_cfg->thresholdDecrement));
+   SET_CHECKED(rf69_set_bandwidth(dev->spi, rx_cfg->bw_mantisse, 
rx_cfg->bw_exponent));
SET_CHECKED(rf69_set_bandwidth_during_afc(dev->spi, 
rx_cfg->bw_mantisse, rx_cfg->bw_exponent));
-   SET_CHECKED(rf69_set_dagc(dev->spi, rx_cfg->dagc));
+   SET_CHECKED(rf69_set_dagc(dev->spi, rx_cfg->dagc));
 
dev->rx_bytes_to_drop = rx_cfg->bytes_to_drop;
 
@@ -959,7 +959,7 @@ static int pi433_release(struct inode *inode, struct file 
*filp)
 
 static int setup_GPIOs(struct pi433_device *device)
 {
-   charname[5];
+   charname[5];
int retval;
int i;
 
diff --git a/drivers/staging/pi433/pi433_if.h b/drivers/staging/pi433/pi433_if.h
index e6ed3cd9b2e2..aae71f029c60 100644
--- a/drivers/staging/pi433/pi433_if.h
+++ b/drivers/staging/pi433/pi433_if.h
@@ -57,7 +57,7 @@
  *
  * NOTE: struct layout is the same in 64bit and 32bit userspace.
  */
-#define PI433_TX_CFG_IOCTL_NR  0
+#define PI433_TX_CFG_IOCTL_NR  0
 struct pi433_tx_cfg
 {
__u32   frequency;
@@ -107,7 +107,7 @@ struct pi433_tx_cfg
  *
  * NOTE: struct layout is the same in 64bit and 32bit userspace.
  */
-#define PI433_RX_CFG_IOCTL_NR  1
+#define PI433_RX_CFG_IOCTL_NR  1
 struct pi433_rx_cfg {
__u32   frequency;
__u16   bit_rate;
diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c
index 7f4db9a1f39a..d931437f0b6a 100644
--- a/drivers/staging/pi433/rf69.c
+++ b/drivers/staging/pi433/rf69.c
@@ -28,8 +28,8 @@
 #include "rf69.h"
 #include "rf69_registers.h"
 
-#define F_OSC3200 /* in Hz */
-#define FIFO_SIZE 66  /* in byte */
+#define F_OSC 3200 /* in Hz */
+#define FIFO_SIZE 66   /* in byte */
 
 /*-*/
 
@@ -885,8 +885,8 @@ int rf69_read_fifo (struct spi_device *spi, u8 *buffer, 
unsigned int size)
/* prepare a bidirectional transfer */
local_buffer[0] = REG_FIFO;
memset(, 0, sizeof(transfer));
-   transfer.tx_buf = local_buffer;
-   transfer.rx_buf = local_buffer;
+   transfer.tx_buf = local_buffer;
+   transfer.rx_buf = local_buffer;
transfer.len= size+1;
 
retval = spi_sync_transfer(spi, , 1);
diff --git a/drivers/staging/pi433/rf69.h b/drivers/staging/pi433/rf69.h
index b81e0762032e..373df64b6891 100644
--- a/drivers/staging/pi433/rf69.h
+++ b/drivers/staging/pi433/rf69.h
@@ -20,10 +20,10 @@
 #include "rf69_enum.h"
 #include "rf69_registers.h"
 
-#define F_OSC  3200  /* in Hz */
+#define F_OSC  3200  /* in Hz */
 #define FREQUENCY  43392 /* in Hz, modifying this value impacts CE 
certification */
-#define FIFO_SIZE  66/* in byte */
-#define FIFO_THRESHOLD 15/* in byte */
+#define FIFO_SIZE  66  /* in byte */
+#define FIFO_THRESHOLD 15  /* in byte */
 
 int rf69_set_mode(struct spi_device *spi, enum mode mode);
 int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode);
-- 
2.13.2



[PATCH 2/3] staging: pi433: - style fix, space before tabs

2017-07-21 Thread Derek Robson
Fixed checkpatch errors of "no space before tabs"

Signed-off-by: Derek Robson 
---
 drivers/staging/pi433/pi433_if.c | 12 ++--
 drivers/staging/pi433/pi433_if.h |  4 ++--
 drivers/staging/pi433/rf69.c |  8 
 drivers/staging/pi433/rf69.h |  6 +++---
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c
index 9cdebe93657c..b9e9292c01d9 100644
--- a/drivers/staging/pi433/pi433_if.c
+++ b/drivers/staging/pi433/pi433_if.c
@@ -190,12 +190,12 @@ rf69_set_rx_cfg(struct pi433_device *dev, struct 
pi433_rx_cfg *rx_cfg)
SET_CHECKED(rf69_set_frequency  (dev->spi, rx_cfg->frequency));
SET_CHECKED(rf69_set_bit_rate   (dev->spi, rx_cfg->bit_rate));
SET_CHECKED(rf69_set_modulation (dev->spi, rx_cfg->modulation));
-   SET_CHECKED(rf69_set_antenna_impedance   (dev->spi, 
rx_cfg->antenna_impedance));
-   SET_CHECKED(rf69_set_rssi_threshold  (dev->spi, 
rx_cfg->rssi_threshold));
-   SET_CHECKED(rf69_set_ook_threshold_dec   (dev->spi, 
rx_cfg->thresholdDecrement));
-   SET_CHECKED(rf69_set_bandwidth   (dev->spi, 
rx_cfg->bw_mantisse, rx_cfg->bw_exponent));
+   SET_CHECKED(rf69_set_antenna_impedance(dev->spi, 
rx_cfg->antenna_impedance));
+   SET_CHECKED(rf69_set_rssi_threshold(dev->spi, rx_cfg->rssi_threshold));
+   SET_CHECKED(rf69_set_ook_threshold_dec(dev->spi, 
rx_cfg->thresholdDecrement));
+   SET_CHECKED(rf69_set_bandwidth(dev->spi, rx_cfg->bw_mantisse, 
rx_cfg->bw_exponent));
SET_CHECKED(rf69_set_bandwidth_during_afc(dev->spi, 
rx_cfg->bw_mantisse, rx_cfg->bw_exponent));
-   SET_CHECKED(rf69_set_dagc(dev->spi, rx_cfg->dagc));
+   SET_CHECKED(rf69_set_dagc(dev->spi, rx_cfg->dagc));
 
dev->rx_bytes_to_drop = rx_cfg->bytes_to_drop;
 
@@ -959,7 +959,7 @@ static int pi433_release(struct inode *inode, struct file 
*filp)
 
 static int setup_GPIOs(struct pi433_device *device)
 {
-   charname[5];
+   charname[5];
int retval;
int i;
 
diff --git a/drivers/staging/pi433/pi433_if.h b/drivers/staging/pi433/pi433_if.h
index e6ed3cd9b2e2..aae71f029c60 100644
--- a/drivers/staging/pi433/pi433_if.h
+++ b/drivers/staging/pi433/pi433_if.h
@@ -57,7 +57,7 @@
  *
  * NOTE: struct layout is the same in 64bit and 32bit userspace.
  */
-#define PI433_TX_CFG_IOCTL_NR  0
+#define PI433_TX_CFG_IOCTL_NR  0
 struct pi433_tx_cfg
 {
__u32   frequency;
@@ -107,7 +107,7 @@ struct pi433_tx_cfg
  *
  * NOTE: struct layout is the same in 64bit and 32bit userspace.
  */
-#define PI433_RX_CFG_IOCTL_NR  1
+#define PI433_RX_CFG_IOCTL_NR  1
 struct pi433_rx_cfg {
__u32   frequency;
__u16   bit_rate;
diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c
index 7f4db9a1f39a..d931437f0b6a 100644
--- a/drivers/staging/pi433/rf69.c
+++ b/drivers/staging/pi433/rf69.c
@@ -28,8 +28,8 @@
 #include "rf69.h"
 #include "rf69_registers.h"
 
-#define F_OSC3200 /* in Hz */
-#define FIFO_SIZE 66  /* in byte */
+#define F_OSC 3200 /* in Hz */
+#define FIFO_SIZE 66   /* in byte */
 
 /*-*/
 
@@ -885,8 +885,8 @@ int rf69_read_fifo (struct spi_device *spi, u8 *buffer, 
unsigned int size)
/* prepare a bidirectional transfer */
local_buffer[0] = REG_FIFO;
memset(, 0, sizeof(transfer));
-   transfer.tx_buf = local_buffer;
-   transfer.rx_buf = local_buffer;
+   transfer.tx_buf = local_buffer;
+   transfer.rx_buf = local_buffer;
transfer.len= size+1;
 
retval = spi_sync_transfer(spi, , 1);
diff --git a/drivers/staging/pi433/rf69.h b/drivers/staging/pi433/rf69.h
index b81e0762032e..373df64b6891 100644
--- a/drivers/staging/pi433/rf69.h
+++ b/drivers/staging/pi433/rf69.h
@@ -20,10 +20,10 @@
 #include "rf69_enum.h"
 #include "rf69_registers.h"
 
-#define F_OSC  3200  /* in Hz */
+#define F_OSC  3200  /* in Hz */
 #define FREQUENCY  43392 /* in Hz, modifying this value impacts CE 
certification */
-#define FIFO_SIZE  66/* in byte */
-#define FIFO_THRESHOLD 15/* in byte */
+#define FIFO_SIZE  66  /* in byte */
+#define FIFO_THRESHOLD 15  /* in byte */
 
 int rf69_set_mode(struct spi_device *spi, enum mode mode);
 int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode);
-- 
2.13.2



[PATCH 1/3] staging: pi433: Style fix - align block comments

2017-07-21 Thread Derek Robson
Fixed the alignment of block comments
Found using checkpatch

Signed-off-by: Derek Robson 
---
 drivers/staging/pi433/pi433_if.c   |  38 +++--
 drivers/staging/pi433/rf69.c   |  10 +-
 drivers/staging/pi433/rf69_registers.h | 280 -
 3 files changed, 169 insertions(+), 159 deletions(-)

diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c
index 1bc478a7f49e..9cdebe93657c 100644
--- a/drivers/staging/pi433/pi433_if.c
+++ b/drivers/staging/pi433/pi433_if.c
@@ -67,9 +67,11 @@ static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */
 static struct class *pi433_class; /* mainly for udev to create /dev/pi433 */
 
 /* tx config is instance specific
-   so with each open a new tx config struct is needed */
+ * so with each open a new tx config struct is needed
+ */
 /* rx config is device specific
-   so we have just one rx config, ebedded in device struct */
+ * so we have just one rx config, ebedded in device struct
+ */
 struct pi433_device {
/* device handling related values */
dev_t   devt;
@@ -486,9 +488,10 @@ pi433_tx_thread(void *data)
return 0;
 
/* get data from fifo in the following order:
-  - tx_cfg
-  - size of message
-  - message */
+* - tx_cfg
+* - size of message
+* - message
+*/
mutex_lock(>tx_fifo_lock);
 
retval = kfifo_out(>tx_fifo, _cfg, sizeof(tx_cfg));
@@ -537,23 +540,26 @@ pi433_tx_thread(void *data)
mutex_unlock(>tx_fifo_lock);
 
/* if rx is active, we need to interrupt the waiting for
-  incoming telegrams, to be able to send something.
-  We are only allowed, if currently no reception takes
-  place otherwise we need to  wait for the incoming telegram
-  to finish */
+* incoming telegrams, to be able to send something.
+* We are only allowed, if currently no reception takes
+* place otherwise we need to  wait for the incoming telegram
+* to finish
+*/
wait_event_interruptible(device->tx_wait_queue,
 !device->rx_active ||
  device->interrupt_rx_allowed == true);
 
/* prevent race conditions
-  irq will be reenabled after tx config is set */
+* irq will be reenabled after tx config is set
+*/
disable_irq(device->irq_num[DIO0]);
device->tx_active = true;
 
if (device->rx_active && rx_interrupted == false)
{
/* rx is currently waiting for a telegram;
-  we need to set the radio module to standby */
+* we need to set the radio module to standby
+*/
SET_CHECKED(rf69_set_mode(device->spi, standby));
rx_interrupted = true;
}
@@ -712,9 +718,10 @@ pi433_write(struct file *filp, const char __user *buf,
return -EMSGSIZE;
 
/* write the following sequence into fifo:
-  - tx_cfg
-  - size of message
-  - message */
+* - tx_cfg
+* - size of message
+* - message
+*/
mutex_lock(>tx_fifo_lock);
retval = kfifo_in(>tx_fifo, >tx_cfg, 
sizeof(instance->tx_cfg));
if ( retval != sizeof(instance->tx_cfg) )
@@ -1269,7 +1276,8 @@ static int __init pi433_init(void)
int status;
 
/* If MAX_MSG_SIZE is smaller then FIFO_SIZE, the driver won't
-   work stable - risk of buffer overflow */
+* work stable - risk of buffer overflow
+*/
if (MAX_MSG_SIZE < FIFO_SIZE)
return -EINVAL;
 
diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c
index e391ce777bc7..7f4db9a1f39a 100644
--- a/drivers/staging/pi433/rf69.c
+++ b/drivers/staging/pi433/rf69.c
@@ -939,8 +939,9 @@ u8 rf69_read_reg(struct spi_device *spi, u8 addr)
#ifdef DEBUG_VALUES
if (retval < 0)
/* should never happen, since we already checked,
-  that module is connected. Therefore no error
-  handling, just an optional error message... */
+* that module is connected. Therefore no error
+* handling, just an optional error message...
+*/
dev_dbg(>dev, "read 0x%x FAILED\n",
addr);
else
@@ -965,8 +966,9 @@ int rf69_write_reg(struct spi_device *spi, u8 addr, u8 
value)
#ifdef 

[PATCH 1/3] staging: pi433: Style fix - align block comments

2017-07-21 Thread Derek Robson
Fixed the alignment of block comments
Found using checkpatch

Signed-off-by: Derek Robson 
---
 drivers/staging/pi433/pi433_if.c   |  38 +++--
 drivers/staging/pi433/rf69.c   |  10 +-
 drivers/staging/pi433/rf69_registers.h | 280 -
 3 files changed, 169 insertions(+), 159 deletions(-)

diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c
index 1bc478a7f49e..9cdebe93657c 100644
--- a/drivers/staging/pi433/pi433_if.c
+++ b/drivers/staging/pi433/pi433_if.c
@@ -67,9 +67,11 @@ static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */
 static struct class *pi433_class; /* mainly for udev to create /dev/pi433 */
 
 /* tx config is instance specific
-   so with each open a new tx config struct is needed */
+ * so with each open a new tx config struct is needed
+ */
 /* rx config is device specific
-   so we have just one rx config, ebedded in device struct */
+ * so we have just one rx config, ebedded in device struct
+ */
 struct pi433_device {
/* device handling related values */
dev_t   devt;
@@ -486,9 +488,10 @@ pi433_tx_thread(void *data)
return 0;
 
/* get data from fifo in the following order:
-  - tx_cfg
-  - size of message
-  - message */
+* - tx_cfg
+* - size of message
+* - message
+*/
mutex_lock(>tx_fifo_lock);
 
retval = kfifo_out(>tx_fifo, _cfg, sizeof(tx_cfg));
@@ -537,23 +540,26 @@ pi433_tx_thread(void *data)
mutex_unlock(>tx_fifo_lock);
 
/* if rx is active, we need to interrupt the waiting for
-  incoming telegrams, to be able to send something.
-  We are only allowed, if currently no reception takes
-  place otherwise we need to  wait for the incoming telegram
-  to finish */
+* incoming telegrams, to be able to send something.
+* We are only allowed, if currently no reception takes
+* place otherwise we need to  wait for the incoming telegram
+* to finish
+*/
wait_event_interruptible(device->tx_wait_queue,
 !device->rx_active ||
  device->interrupt_rx_allowed == true);
 
/* prevent race conditions
-  irq will be reenabled after tx config is set */
+* irq will be reenabled after tx config is set
+*/
disable_irq(device->irq_num[DIO0]);
device->tx_active = true;
 
if (device->rx_active && rx_interrupted == false)
{
/* rx is currently waiting for a telegram;
-  we need to set the radio module to standby */
+* we need to set the radio module to standby
+*/
SET_CHECKED(rf69_set_mode(device->spi, standby));
rx_interrupted = true;
}
@@ -712,9 +718,10 @@ pi433_write(struct file *filp, const char __user *buf,
return -EMSGSIZE;
 
/* write the following sequence into fifo:
-  - tx_cfg
-  - size of message
-  - message */
+* - tx_cfg
+* - size of message
+* - message
+*/
mutex_lock(>tx_fifo_lock);
retval = kfifo_in(>tx_fifo, >tx_cfg, 
sizeof(instance->tx_cfg));
if ( retval != sizeof(instance->tx_cfg) )
@@ -1269,7 +1276,8 @@ static int __init pi433_init(void)
int status;
 
/* If MAX_MSG_SIZE is smaller then FIFO_SIZE, the driver won't
-   work stable - risk of buffer overflow */
+* work stable - risk of buffer overflow
+*/
if (MAX_MSG_SIZE < FIFO_SIZE)
return -EINVAL;
 
diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c
index e391ce777bc7..7f4db9a1f39a 100644
--- a/drivers/staging/pi433/rf69.c
+++ b/drivers/staging/pi433/rf69.c
@@ -939,8 +939,9 @@ u8 rf69_read_reg(struct spi_device *spi, u8 addr)
#ifdef DEBUG_VALUES
if (retval < 0)
/* should never happen, since we already checked,
-  that module is connected. Therefore no error
-  handling, just an optional error message... */
+* that module is connected. Therefore no error
+* handling, just an optional error message...
+*/
dev_dbg(>dev, "read 0x%x FAILED\n",
addr);
else
@@ -965,8 +966,9 @@ int rf69_write_reg(struct spi_device *spi, u8 addr, u8 
value)
#ifdef DEBUG_VALUES
  

[PATCH 0/3] Drivers: pi433: Style fix

2017-07-21 Thread Derek Robson
Assorted styel fix across whole driver
Found using checkpatch



Derek Robson (3):
  staging: pi433: Style fix - align block comments
  staging: pi433: - style fix, space before tabs
  staging: pi433: - style fix, space at start of line

 drivers/staging/pi433/pi433_if.c   |  50 +++---
 drivers/staging/pi433/pi433_if.h   |   4 +-
 drivers/staging/pi433/rf69.c   |  22 +--
 drivers/staging/pi433/rf69.h   |   6 +-
 drivers/staging/pi433/rf69_enum.h  | 206 
 drivers/staging/pi433/rf69_registers.h | 280 -
 6 files changed, 289 insertions(+), 279 deletions(-)

-- 
2.13.2



[PATCH 0/3] Drivers: pi433: Style fix

2017-07-21 Thread Derek Robson
Assorted styel fix across whole driver
Found using checkpatch



Derek Robson (3):
  staging: pi433: Style fix - align block comments
  staging: pi433: - style fix, space before tabs
  staging: pi433: - style fix, space at start of line

 drivers/staging/pi433/pi433_if.c   |  50 +++---
 drivers/staging/pi433/pi433_if.h   |   4 +-
 drivers/staging/pi433/rf69.c   |  22 +--
 drivers/staging/pi433/rf69.h   |   6 +-
 drivers/staging/pi433/rf69_enum.h  | 206 
 drivers/staging/pi433/rf69_registers.h | 280 -
 6 files changed, 289 insertions(+), 279 deletions(-)

-- 
2.13.2



Re: [PATCH v3 1/3] string.h: add memcpy_and_pad()

2017-07-21 Thread kbuild test robot
Hi Martin,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.13-rc1 next-20170721]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Martin-Wilck/Improve-readbility-of-NVME-wwid-attribute/20170722-110309
config: x86_64-randconfig-x005-201729 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   In file included from include/uapi/linux/stddef.h:1:0,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/linux/mod_devicetable.h:11,
from scripts/mod/devicetable-offsets.c:2:
>> include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
>> inline function 'memcpy_and_pad' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:421:2: note: in expansion of macro 'if'
 if (dest_len > count) {
 ^~
>> include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
>> inline function 'memcpy_and_pad' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:419:2: note: in expansion of macro 'if'
 if (dest_size < dest_len)
 ^~
>> include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
>> inline function 'memcpy_and_pad' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:416:8: note: in expansion of macro 'if'
  else if (src_size < dest_len && src_size < count)
   ^~
>> include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
>> inline function 'memcpy_and_pad' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:414:3: note: in expansion of macro 'if'
  if (dest_size < dest_len && dest_size < count)
  ^~
>> include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
>> inline function 'memcpy_and_pad' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:413:2: note: in expansion of macro 'if'
 if (__builtin_constant_p(dest_len) && __builtin_constant_p(count)) {
 ^~
   include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
inline function 'strcpy' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:391:2: note: in expansion of macro 'if'
 if (p_size == (size_t)-1 && q_size == (size_t)-1)
 ^~
   include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
inline function 'kmemdup' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:381:2: note: in expansion of macro 'if'
 if (p_size < size)
 ^~
   include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
inline function 'kmemdup' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:379:2: note: in expansion of macro 'if'
 if (__builtin_constant_p(size) && p_size < size)
 ^~
   include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
inline function 'memchr_inv' which is not static
   __f = { \

Re: [PATCH v3 1/3] string.h: add memcpy_and_pad()

2017-07-21 Thread kbuild test robot
Hi Martin,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.13-rc1 next-20170721]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Martin-Wilck/Improve-readbility-of-NVME-wwid-attribute/20170722-110309
config: x86_64-randconfig-x005-201729 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   In file included from include/uapi/linux/stddef.h:1:0,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/linux/mod_devicetable.h:11,
from scripts/mod/devicetable-offsets.c:2:
>> include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
>> inline function 'memcpy_and_pad' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:421:2: note: in expansion of macro 'if'
 if (dest_len > count) {
 ^~
>> include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
>> inline function 'memcpy_and_pad' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:419:2: note: in expansion of macro 'if'
 if (dest_size < dest_len)
 ^~
>> include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
>> inline function 'memcpy_and_pad' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:416:8: note: in expansion of macro 'if'
  else if (src_size < dest_len && src_size < count)
   ^~
>> include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
>> inline function 'memcpy_and_pad' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:414:3: note: in expansion of macro 'if'
  if (dest_size < dest_len && dest_size < count)
  ^~
>> include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
>> inline function 'memcpy_and_pad' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:413:2: note: in expansion of macro 'if'
 if (__builtin_constant_p(dest_len) && __builtin_constant_p(count)) {
 ^~
   include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
inline function 'strcpy' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:391:2: note: in expansion of macro 'if'
 if (p_size == (size_t)-1 && q_size == (size_t)-1)
 ^~
   include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
inline function 'kmemdup' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:381:2: note: in expansion of macro 'if'
 if (p_size < size)
 ^~
   include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
inline function 'kmemdup' which is not static
   __f = { \
   ^
   include/linux/compiler.h:154:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  ^~
   include/linux/string.h:379:2: note: in expansion of macro 'if'
 if (__builtin_constant_p(size) && p_size < size)
 ^~
   include/linux/compiler.h:162:4: warning: '__f' is static but declared in 
inline function 'memchr_inv' which is not static
   __f = { \

Re: [PATCH] irqchip/gic-v3-its: Allow GIC ITS number more than MAX_NUMNODES

2017-07-21 Thread Hanjun Guo
On 2017/7/21 19:20, Marc Zyngier wrote:
> On 21/07/17 11:06, Hanjun Guo wrote:
>> On 2017/7/21 17:51, Hanjun Guo wrote:
>>> From: Hanjun Guo 
>>>
>>> When running 4.13-rc1 on top of D05, I got the boot log:
>>>
>>> [0.00] SRAT: PXM 0 -> ITS 0 -> Node 0
>>> [0.00] SRAT: PXM 0 -> ITS 1 -> Node 0
>>> [0.00] SRAT: PXM 0 -> ITS 2 -> Node 0
>>> [0.00] SRAT: PXM 1 -> ITS 3 -> Node 1
>>> [0.00] SRAT: ITS affinity exceeding max count[4]
>>>
>>> This is wrong on D05 as we have 8 ITSes with 4 NUMA nodes.
> I'm not seeing this on the D05 I have access to. Actually, I'm not
> seeing any data related to SRAT and the ITS. Is that a different firmware?

Yes, actually it's just a updated version in this week, that's why
the bug wasn't be spotted when Ganapat's patch was merged.

>
>>> So dynamically alloc the memory needed instead of using
>>> its_srat_maps[MAX_NUMNODES], which count the number of
>>> ITS entry(ies) in SRAT and alloc its_srat_maps as needed,
>>> then build the mapping of numa node to ITS ID.
>>>
>>> After doing this, I got what I wanted:
>>>
>>> [0.00] SRAT: PXM 0 -> ITS 0 -> Node 0
>>> [0.00] SRAT: PXM 0 -> ITS 1 -> Node 0
>>> [0.00] SRAT: PXM 0 -> ITS 2 -> Node 0
>>> [0.00] SRAT: PXM 1 -> ITS 3 -> Node 1
>>> [0.00] SRAT: PXM 2 -> ITS 4 -> Node 2
>>> [0.00] SRAT: PXM 2 -> ITS 5 -> Node 2
>>> [0.00] SRAT: PXM 2 -> ITS 6 -> Node 2
>>> [0.00] SRAT: PXM 3 -> ITS 7 -> Node 3
>>>
>>> Fixes: dbd2b8267233 ("irqchip/gic-v3-its: Add ACPI NUMA node mapping")
>>> Signed-off-by: Hanjun Guo 
>>> Cc: Ganapatrao Kulkarni 
>>> Cc: Lorenzo Pieralisi 
>>> Cc: Marc Zyngier 
>>> ---
>>>  drivers/irqchip/irq-gic-v3-its.c | 28 +---
>>>  1 file changed, 21 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3-its.c 
>>> b/drivers/irqchip/irq-gic-v3-its.c
>>> index 3ccdf76..fb1c090 100644
>>> --- a/drivers/irqchip/irq-gic-v3-its.c
>>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>>> @@ -1847,7 +1847,7 @@ struct its_srat_map {
>>> u32 its_id;
>>>  };
>>>  
>>> -static struct its_srat_map its_srat_maps[MAX_NUMNODES] __initdata;
>>> +static struct its_srat_map *its_srat_maps __initdata;
>>>  static int its_in_srat __initdata;
>>>  
>>>  static int __init acpi_get_its_numa_node(u32 its_id)
>>> @@ -1861,6 +1861,12 @@ static int __init acpi_get_its_numa_node(u32 its_id)
>>> return NUMA_NO_NODE;
>>>  }
>> Oops, need to check if the its_srat_maps valid or not here, please
>> comment on what else I'm missing or wrong, then I will prepare another
>> version.
> Please post a patch that has all of the fixes, and I'll review that.

Will do that later.

Thanks
Hanjun



Re: [PATCH] irqchip/gic-v3-its: Allow GIC ITS number more than MAX_NUMNODES

2017-07-21 Thread Hanjun Guo
On 2017/7/21 19:20, Marc Zyngier wrote:
> On 21/07/17 11:06, Hanjun Guo wrote:
>> On 2017/7/21 17:51, Hanjun Guo wrote:
>>> From: Hanjun Guo 
>>>
>>> When running 4.13-rc1 on top of D05, I got the boot log:
>>>
>>> [0.00] SRAT: PXM 0 -> ITS 0 -> Node 0
>>> [0.00] SRAT: PXM 0 -> ITS 1 -> Node 0
>>> [0.00] SRAT: PXM 0 -> ITS 2 -> Node 0
>>> [0.00] SRAT: PXM 1 -> ITS 3 -> Node 1
>>> [0.00] SRAT: ITS affinity exceeding max count[4]
>>>
>>> This is wrong on D05 as we have 8 ITSes with 4 NUMA nodes.
> I'm not seeing this on the D05 I have access to. Actually, I'm not
> seeing any data related to SRAT and the ITS. Is that a different firmware?

Yes, actually it's just a updated version in this week, that's why
the bug wasn't be spotted when Ganapat's patch was merged.

>
>>> So dynamically alloc the memory needed instead of using
>>> its_srat_maps[MAX_NUMNODES], which count the number of
>>> ITS entry(ies) in SRAT and alloc its_srat_maps as needed,
>>> then build the mapping of numa node to ITS ID.
>>>
>>> After doing this, I got what I wanted:
>>>
>>> [0.00] SRAT: PXM 0 -> ITS 0 -> Node 0
>>> [0.00] SRAT: PXM 0 -> ITS 1 -> Node 0
>>> [0.00] SRAT: PXM 0 -> ITS 2 -> Node 0
>>> [0.00] SRAT: PXM 1 -> ITS 3 -> Node 1
>>> [0.00] SRAT: PXM 2 -> ITS 4 -> Node 2
>>> [0.00] SRAT: PXM 2 -> ITS 5 -> Node 2
>>> [0.00] SRAT: PXM 2 -> ITS 6 -> Node 2
>>> [0.00] SRAT: PXM 3 -> ITS 7 -> Node 3
>>>
>>> Fixes: dbd2b8267233 ("irqchip/gic-v3-its: Add ACPI NUMA node mapping")
>>> Signed-off-by: Hanjun Guo 
>>> Cc: Ganapatrao Kulkarni 
>>> Cc: Lorenzo Pieralisi 
>>> Cc: Marc Zyngier 
>>> ---
>>>  drivers/irqchip/irq-gic-v3-its.c | 28 +---
>>>  1 file changed, 21 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3-its.c 
>>> b/drivers/irqchip/irq-gic-v3-its.c
>>> index 3ccdf76..fb1c090 100644
>>> --- a/drivers/irqchip/irq-gic-v3-its.c
>>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>>> @@ -1847,7 +1847,7 @@ struct its_srat_map {
>>> u32 its_id;
>>>  };
>>>  
>>> -static struct its_srat_map its_srat_maps[MAX_NUMNODES] __initdata;
>>> +static struct its_srat_map *its_srat_maps __initdata;
>>>  static int its_in_srat __initdata;
>>>  
>>>  static int __init acpi_get_its_numa_node(u32 its_id)
>>> @@ -1861,6 +1861,12 @@ static int __init acpi_get_its_numa_node(u32 its_id)
>>> return NUMA_NO_NODE;
>>>  }
>> Oops, need to check if the its_srat_maps valid or not here, please
>> comment on what else I'm missing or wrong, then I will prepare another
>> version.
> Please post a patch that has all of the fixes, and I'll review that.

Will do that later.

Thanks
Hanjun



[PATCH v7 05/12] clk: Kconfig: Name RK805 in Kconfig for COMMON_CLK_RK808

2017-07-21 Thread Joseph Chen
From: Elaine Zhang 

The RK808 and RK805 PMICs are using a similar register map.
We can reuse the clk driver for the RK805 PMIC. So let's add
the RK805 in the Kconfig description.

Signed-off-by: Elaine Zhang 
---
 drivers/clk/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 9356ab4..7ca8f02 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -39,10 +39,10 @@ config COMMON_CLK_MAX77686
  clock.
 
 config COMMON_CLK_RK808
-   tristate "Clock driver for RK808/RK818"
+   tristate "Clock driver for RK805/RK808/RK818"
depends on MFD_RK808
---help---
- This driver supports RK808 and RK818 crystal oscillator clock. These
+ This driver supports RK805, RK808 and RK818 crystal oscillator clock. 
These
  multi-function devices have two fixed-rate oscillators,
  clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
  by control register.
-- 
1.9.1




[PATCH v7 05/12] clk: Kconfig: Name RK805 in Kconfig for COMMON_CLK_RK808

2017-07-21 Thread Joseph Chen
From: Elaine Zhang 

The RK808 and RK805 PMICs are using a similar register map.
We can reuse the clk driver for the RK805 PMIC. So let's add
the RK805 in the Kconfig description.

Signed-off-by: Elaine Zhang 
---
 drivers/clk/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 9356ab4..7ca8f02 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -39,10 +39,10 @@ config COMMON_CLK_MAX77686
  clock.
 
 config COMMON_CLK_RK808
-   tristate "Clock driver for RK808/RK818"
+   tristate "Clock driver for RK805/RK808/RK818"
depends on MFD_RK808
---help---
- This driver supports RK808 and RK818 crystal oscillator clock. These
+ This driver supports RK805, RK808 and RK818 crystal oscillator clock. 
These
  multi-function devices have two fixed-rate oscillators,
  clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
  by control register.
-- 
1.9.1




Re: [PATCH v6 0/2] x86: Implement fast refcount overflow protection

2017-07-21 Thread Kees Cook
On Fri, Jul 21, 2017 at 2:22 PM, Andrew Morton
 wrote:
> On Thu, 20 Jul 2017 11:11:06 +0200 Ingo Molnar  wrote:
>
>>
>> * Kees Cook  wrote:
>>
>> > This implements refcount_t overflow protection on x86 without a noticeable
>> > performance impact, though without the fuller checking of REFCOUNT_FULL.
>> > This is done by duplicating the existing atomic_t refcount implementation
>> > but with normally a single instruction added to detect if the refcount
>> > has gone negative (i.e. wrapped past INT_MAX or below zero). When
>> > detected, the handler saturates the refcount_t to INT_MIN / 2. With this
>> > overflow protection, the erroneous reference release that would follow
>> > a wrap back to zero is blocked from happening, avoiding the class of
>> > refcount-over-increment use-after-free vulnerabilities entirely.
>> >
>> > Only the overflow case of refcounting can be perfectly protected, since it
>> > can be detected and stopped before the reference is freed and left to be
>> > abused by an attacker. This implementation also notices some of the "dec
>> > to 0 without test", and "below 0" cases. However, these only indicate that
>> > a use-after-free may have already happened. Such notifications are likely
>> > avoidable by an attacker that has already exploited a use-after-free
>> > vulnerability, but it's better to have them than allow such conditions to
>> > remain universally silent.
>> >
>> > On first overflow detection, the refcount value is reset to INT_MIN / 2
>> > (which serves as a saturation value), the offending process is killed,
>> > and a report and stack trace are produced. When operations detect only
>> > negative value results (such as changing an already saturated value),
>> > saturation still happens but no notification is performed (since the
>> > value was already saturated).
>> >
>> > On the matter of races, since the entire range beyond INT_MAX but before
>> > 0 is negative, every operation at INT_MIN / 2 will trap, leaving no
>> > overflow-only race condition.
>> >
>> > As for performance, this implementation adds a single "js" instruction
>> > to the regular execution flow of a copy of the standard atomic_t refcount
>> > operations. (The non-"and_test" refcount_dec() function, which is uncommon
>> > in regular refcount design patterns, has an additional "jz" instruction
>> > to detect reaching exactly zero.) Since this is a forward jump, it is by
>> > default the non-predicted path, which will be reinforced by dynamic branch
>> > prediction. The result is this protection having virtually no measurable
>> > change in performance over standard atomic_t operations. The error path,
>> > located in .text.unlikely, saves the refcount location and then uses UD0
>> > to fire a refcount exception handler, which resets the refcount, handles
>> > reporting, and returns to regular execution. This keeps the changes to
>> > .text size minimal, avoiding return jumps and open-coded calls to the
>> > error reporting routine.
>>
>> Pretty nice!
>>
>
> Yes, this is a relief.
>
> Do we have a feeling for how feasible/difficult it will be for other
> architectures to implement such a thing?

The PaX atomic_t overflow protection this is heavily based on was
ported to a number of architectures (arm, powerpc, mips, sparc), so I
suspect it shouldn't be too hard to adapt those for the more narrow
refcount_t protection:
https://forums.grsecurity.net/viewtopic.php?f=7=4173

And an arm64 port of the fast refcount_t protection is already happening too.

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH v6 0/2] x86: Implement fast refcount overflow protection

2017-07-21 Thread Kees Cook
On Fri, Jul 21, 2017 at 2:22 PM, Andrew Morton
 wrote:
> On Thu, 20 Jul 2017 11:11:06 +0200 Ingo Molnar  wrote:
>
>>
>> * Kees Cook  wrote:
>>
>> > This implements refcount_t overflow protection on x86 without a noticeable
>> > performance impact, though without the fuller checking of REFCOUNT_FULL.
>> > This is done by duplicating the existing atomic_t refcount implementation
>> > but with normally a single instruction added to detect if the refcount
>> > has gone negative (i.e. wrapped past INT_MAX or below zero). When
>> > detected, the handler saturates the refcount_t to INT_MIN / 2. With this
>> > overflow protection, the erroneous reference release that would follow
>> > a wrap back to zero is blocked from happening, avoiding the class of
>> > refcount-over-increment use-after-free vulnerabilities entirely.
>> >
>> > Only the overflow case of refcounting can be perfectly protected, since it
>> > can be detected and stopped before the reference is freed and left to be
>> > abused by an attacker. This implementation also notices some of the "dec
>> > to 0 without test", and "below 0" cases. However, these only indicate that
>> > a use-after-free may have already happened. Such notifications are likely
>> > avoidable by an attacker that has already exploited a use-after-free
>> > vulnerability, but it's better to have them than allow such conditions to
>> > remain universally silent.
>> >
>> > On first overflow detection, the refcount value is reset to INT_MIN / 2
>> > (which serves as a saturation value), the offending process is killed,
>> > and a report and stack trace are produced. When operations detect only
>> > negative value results (such as changing an already saturated value),
>> > saturation still happens but no notification is performed (since the
>> > value was already saturated).
>> >
>> > On the matter of races, since the entire range beyond INT_MAX but before
>> > 0 is negative, every operation at INT_MIN / 2 will trap, leaving no
>> > overflow-only race condition.
>> >
>> > As for performance, this implementation adds a single "js" instruction
>> > to the regular execution flow of a copy of the standard atomic_t refcount
>> > operations. (The non-"and_test" refcount_dec() function, which is uncommon
>> > in regular refcount design patterns, has an additional "jz" instruction
>> > to detect reaching exactly zero.) Since this is a forward jump, it is by
>> > default the non-predicted path, which will be reinforced by dynamic branch
>> > prediction. The result is this protection having virtually no measurable
>> > change in performance over standard atomic_t operations. The error path,
>> > located in .text.unlikely, saves the refcount location and then uses UD0
>> > to fire a refcount exception handler, which resets the refcount, handles
>> > reporting, and returns to regular execution. This keeps the changes to
>> > .text size minimal, avoiding return jumps and open-coded calls to the
>> > error reporting routine.
>>
>> Pretty nice!
>>
>
> Yes, this is a relief.
>
> Do we have a feeling for how feasible/difficult it will be for other
> architectures to implement such a thing?

The PaX atomic_t overflow protection this is heavily based on was
ported to a number of architectures (arm, powerpc, mips, sparc), so I
suspect it shouldn't be too hard to adapt those for the more narrow
refcount_t protection:
https://forums.grsecurity.net/viewtopic.php?f=7=4173

And an arm64 port of the fast refcount_t protection is already happening too.

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH v3 2/2] acpi/iort: numa: Add numa node mapping for smmuv3 devices

2017-07-21 Thread Hanjun Guo
Hi Ganapat,

On 2017/6/8 12:44, Ganapatrao Kulkarni wrote:
> Add code to parse proximity domain in SMMUv3 IORT table to
> set numa node mapping for smmuv3 devices.
>
> Signed-off-by: Ganapatrao Kulkarni 
> ---
>  drivers/acpi/arm64/iort.c | 28 ++--
>  1 file changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index bba2b59..e804386 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -882,6 +882,23 @@ static bool __init arm_smmu_v3_is_coherent(struct 
> acpi_iort_node *node)
>   return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
>  }
>  
> +/*
> + * set numa proximity domain for smmuv3 device
> + */
> +static void  __init arm_smmu_v3_set_proximity(struct acpi_iort_node *node,
> + struct device *dev)
> +{
> + struct acpi_iort_smmu_v3 *smmu;
> +
> + smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
> + if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) {
> + set_dev_node(dev, acpi_map_pxm_to_node(smmu->pxm));
  ^^
Will have compile error in !CONFIG_NUMA, I think we need to introduce
a stub function in acpi_numa.h.

Thanks
Hanjun



Re: [PATCH v3 2/2] acpi/iort: numa: Add numa node mapping for smmuv3 devices

2017-07-21 Thread Hanjun Guo
Hi Ganapat,

On 2017/6/8 12:44, Ganapatrao Kulkarni wrote:
> Add code to parse proximity domain in SMMUv3 IORT table to
> set numa node mapping for smmuv3 devices.
>
> Signed-off-by: Ganapatrao Kulkarni 
> ---
>  drivers/acpi/arm64/iort.c | 28 ++--
>  1 file changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index bba2b59..e804386 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -882,6 +882,23 @@ static bool __init arm_smmu_v3_is_coherent(struct 
> acpi_iort_node *node)
>   return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
>  }
>  
> +/*
> + * set numa proximity domain for smmuv3 device
> + */
> +static void  __init arm_smmu_v3_set_proximity(struct acpi_iort_node *node,
> + struct device *dev)
> +{
> + struct acpi_iort_smmu_v3 *smmu;
> +
> + smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
> + if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) {
> + set_dev_node(dev, acpi_map_pxm_to_node(smmu->pxm));
  ^^
Will have compile error in !CONFIG_NUMA, I think we need to introduce
a stub function in acpi_numa.h.

Thanks
Hanjun



Re: [PATCH v3 08/10] clk: sunxi-ng: support R40 SoC

2017-07-21 Thread icenowy

在 2017-05-29 15:34,Chen-Yu Tsai 写道:

Hi,

On Sat, May 27, 2017 at 06:23:06PM +0800, Icenowy Zheng wrote:

Allwinner R40 SoC have a clock controller module in the style of the
SoCs beyond sun6i, however, it's more rich and complex.

Add support for it.

Signed-off-by: Icenowy Zheng 
---
Changes in v3:
- Rebased on current linux-next.
Changes in v2:
- Fixes according to the SoC's user manual.

 drivers/clk/sunxi-ng/Kconfig  |   10 +
 drivers/clk/sunxi-ng/Makefile |1 +
 drivers/clk/sunxi-ng/ccu-sun8i-r40.c  | 1153 
+

 drivers/clk/sunxi-ng/ccu-sun8i-r40.h  |   68 ++
 include/dt-bindings/clock/sun8i-r40-ccu.h |  191 +
 include/dt-bindings/reset/sun8i-r40-ccu.h |  129 
 6 files changed, 1552 insertions(+)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r40.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r40.h
 create mode 100644 include/dt-bindings/clock/sun8i-r40-ccu.h
 create mode 100644 include/dt-bindings/reset/sun8i-r40-ccu.h

diff --git a/drivers/clk/sunxi-ng/Kconfig 
b/drivers/clk/sunxi-ng/Kconfig

index 67acef3d2494..c11ad3375907 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -157,6 +157,16 @@ config SUN8I_DE2_CCU
select SUNXI_CCU_DIV
select SUNXI_CCU_GATE

+config SUN8I_R40_CCU
+   bool "Support for the Allwinner R40 CCU"
+   select SUNXI_CCU_DIV
+   select SUNXI_CCU_NK
+   select SUNXI_CCU_NKM
+   select SUNXI_CCU_NKMP
+   select SUNXI_CCU_NM
+   select SUNXI_CCU_MP


You seem to be missing a few, such as CCU_GATE, CCU_MUX, CCU_PHASE.
The list should at least be the same as the included headers.


+   default MACH_SUN8I
+
 config SUN9I_A80_CCU
bool "Support for the Allwinner A80 CCU"
select SUNXI_CCU_DIV
diff --git a/drivers/clk/sunxi-ng/Makefile 
b/drivers/clk/sunxi-ng/Makefile

index 0185c6ffadcb..217db667a994 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SUN8I_H3_CCU)+= ccu-sun8i-h3.o
 obj-$(CONFIG_SUN8I_V3S_CCU)+= ccu-sun8i-v3s.o
 obj-$(CONFIG_SUN8I_DE2_CCU)+= ccu-sun8i-de2.o
 obj-$(CONFIG_SUN8I_R_CCU)  += ccu-sun8i-r.o
+obj-$(CONFIG_SUN8I_R40_CCU)+= ccu-sun8i-r40.o
 obj-$(CONFIG_SUN9I_A80_CCU)+= ccu-sun9i-a80.o
 obj-$(CONFIG_SUN9I_A80_CCU)+= ccu-sun9i-a80-de.o
 obj-$(CONFIG_SUN9I_A80_CCU)+= ccu-sun9i-a80-usb.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c 
b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c

new file mode 100644
index ..484a8956f59c
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
@@ -0,0 +1,1153 @@
+/*
+ * Copyright (c) 2017 Icenowy Zheng 
+ *
+ * This software is licensed under the terms of the GNU General 
Public
+ * License version 2, as published by the Free Software Foundation, 
and

+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include 
+#include 
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+#include "ccu_phase.h"
+
+#include "ccu-sun8i-r40.h"
+
+static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
+"osc24M", 0x000,
+8, 5,  /* N */
+4, 2,  /* K */
+0, 2,  /* M */
+16, 2, /* P */


P does not do /8. Please add a limit.


+BIT(31),   /* gate */
+BIT(28),   /* lock */
+0);
+
+/*
+ * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
+ * the base (2x, 4x and 8x), and one variable divider (the one true
+ * pll audio).
+ *
+ * We don't have any need for the variable divider for now, so we 
just

+ * hardcode it to match with the clock names
+ */
+#define SUN8I_R40_PLL_AUDIO_REG0x008
+
+static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, 
"pll-audio-base",

+  "osc24M", 0x008,
+  8, 7,/* N */
+  0, 5,/* M */
+  BIT(31), /* gate */
+  BIT(28), /* lock */
+  0);
+
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
+   "osc24M", 0x0010,
+   8, 7,   /* N */
+  

Re: [PATCH v3 08/10] clk: sunxi-ng: support R40 SoC

2017-07-21 Thread icenowy

在 2017-05-29 15:34,Chen-Yu Tsai 写道:

Hi,

On Sat, May 27, 2017 at 06:23:06PM +0800, Icenowy Zheng wrote:

Allwinner R40 SoC have a clock controller module in the style of the
SoCs beyond sun6i, however, it's more rich and complex.

Add support for it.

Signed-off-by: Icenowy Zheng 
---
Changes in v3:
- Rebased on current linux-next.
Changes in v2:
- Fixes according to the SoC's user manual.

 drivers/clk/sunxi-ng/Kconfig  |   10 +
 drivers/clk/sunxi-ng/Makefile |1 +
 drivers/clk/sunxi-ng/ccu-sun8i-r40.c  | 1153 
+

 drivers/clk/sunxi-ng/ccu-sun8i-r40.h  |   68 ++
 include/dt-bindings/clock/sun8i-r40-ccu.h |  191 +
 include/dt-bindings/reset/sun8i-r40-ccu.h |  129 
 6 files changed, 1552 insertions(+)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r40.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r40.h
 create mode 100644 include/dt-bindings/clock/sun8i-r40-ccu.h
 create mode 100644 include/dt-bindings/reset/sun8i-r40-ccu.h

diff --git a/drivers/clk/sunxi-ng/Kconfig 
b/drivers/clk/sunxi-ng/Kconfig

index 67acef3d2494..c11ad3375907 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -157,6 +157,16 @@ config SUN8I_DE2_CCU
select SUNXI_CCU_DIV
select SUNXI_CCU_GATE

+config SUN8I_R40_CCU
+   bool "Support for the Allwinner R40 CCU"
+   select SUNXI_CCU_DIV
+   select SUNXI_CCU_NK
+   select SUNXI_CCU_NKM
+   select SUNXI_CCU_NKMP
+   select SUNXI_CCU_NM
+   select SUNXI_CCU_MP


You seem to be missing a few, such as CCU_GATE, CCU_MUX, CCU_PHASE.
The list should at least be the same as the included headers.


+   default MACH_SUN8I
+
 config SUN9I_A80_CCU
bool "Support for the Allwinner A80 CCU"
select SUNXI_CCU_DIV
diff --git a/drivers/clk/sunxi-ng/Makefile 
b/drivers/clk/sunxi-ng/Makefile

index 0185c6ffadcb..217db667a994 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SUN8I_H3_CCU)+= ccu-sun8i-h3.o
 obj-$(CONFIG_SUN8I_V3S_CCU)+= ccu-sun8i-v3s.o
 obj-$(CONFIG_SUN8I_DE2_CCU)+= ccu-sun8i-de2.o
 obj-$(CONFIG_SUN8I_R_CCU)  += ccu-sun8i-r.o
+obj-$(CONFIG_SUN8I_R40_CCU)+= ccu-sun8i-r40.o
 obj-$(CONFIG_SUN9I_A80_CCU)+= ccu-sun9i-a80.o
 obj-$(CONFIG_SUN9I_A80_CCU)+= ccu-sun9i-a80-de.o
 obj-$(CONFIG_SUN9I_A80_CCU)+= ccu-sun9i-a80-usb.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c 
b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c

new file mode 100644
index ..484a8956f59c
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
@@ -0,0 +1,1153 @@
+/*
+ * Copyright (c) 2017 Icenowy Zheng 
+ *
+ * This software is licensed under the terms of the GNU General 
Public
+ * License version 2, as published by the Free Software Foundation, 
and

+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include 
+#include 
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+#include "ccu_phase.h"
+
+#include "ccu-sun8i-r40.h"
+
+static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
+"osc24M", 0x000,
+8, 5,  /* N */
+4, 2,  /* K */
+0, 2,  /* M */
+16, 2, /* P */


P does not do /8. Please add a limit.


+BIT(31),   /* gate */
+BIT(28),   /* lock */
+0);
+
+/*
+ * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
+ * the base (2x, 4x and 8x), and one variable divider (the one true
+ * pll audio).
+ *
+ * We don't have any need for the variable divider for now, so we 
just

+ * hardcode it to match with the clock names
+ */
+#define SUN8I_R40_PLL_AUDIO_REG0x008
+
+static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, 
"pll-audio-base",

+  "osc24M", 0x008,
+  8, 7,/* N */
+  0, 5,/* M */
+  BIT(31), /* gate */
+  BIT(28), /* lock */
+  0);
+
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
+   "osc24M", 0x0010,
+   8, 7,   /* N */
+   0, 4,

Re: Moving ndctl development into the kernel tree?

2017-07-21 Thread Dan Williams
[ adding Chris ]

On Fri, Jul 21, 2017 at 4:44 PM, Dan Williams  wrote:
> On Fri, Jul 21, 2017 at 3:58 PM, Ingo Molnar  wrote:
>>
>> * Dan Williams  wrote:
>>
>>> [...]
>>>
>>> * Like perf, ndctl borrows the sub-command architecture and option
>>> parsing from git. So, this code could be refactored into something
>>> shared / generic, i.e. the bits in tools/perf/util/.
>>
>> Just as a side note, stacktool (tools/stacktool/) is using the Git 
>> sub-command and
>> options parsing code as well, and it's already sharing it with perf, via the
>> tools/lib/subcmd/ library.
>>
>> ndctl could use that as well.
>
> Ah, nice, that refactoring happened about a year after ndctl was born.
> Which brings up the next question about what to do with the git
> history, but I'd want to know if ndctl is even welcome upstream before
> digging any deeper.

I suspect this would be similar to what Chris did to merge btrfs while
retaining the standalone history. Chris, any pointers on what worked
well and what if anything you would do differently? I.e. I'm looking
to use git filter-branch to rewrite ndctl history as if if had always
been in tools/ndctl in the kernel tree. I found this old thread
https://lkml.org/lkml/2008/10/30/523 and it seems to also recommend
using an older kernel as the branch base.


Re: Moving ndctl development into the kernel tree?

2017-07-21 Thread Dan Williams
[ adding Chris ]

On Fri, Jul 21, 2017 at 4:44 PM, Dan Williams  wrote:
> On Fri, Jul 21, 2017 at 3:58 PM, Ingo Molnar  wrote:
>>
>> * Dan Williams  wrote:
>>
>>> [...]
>>>
>>> * Like perf, ndctl borrows the sub-command architecture and option
>>> parsing from git. So, this code could be refactored into something
>>> shared / generic, i.e. the bits in tools/perf/util/.
>>
>> Just as a side note, stacktool (tools/stacktool/) is using the Git 
>> sub-command and
>> options parsing code as well, and it's already sharing it with perf, via the
>> tools/lib/subcmd/ library.
>>
>> ndctl could use that as well.
>
> Ah, nice, that refactoring happened about a year after ndctl was born.
> Which brings up the next question about what to do with the git
> history, but I'd want to know if ndctl is even welcome upstream before
> digging any deeper.

I suspect this would be similar to what Chris did to merge btrfs while
retaining the standalone history. Chris, any pointers on what worked
well and what if anything you would do differently? I.e. I'm looking
to use git filter-branch to rewrite ndctl history as if if had always
been in tools/ndctl in the kernel tree. I found this old thread
https://lkml.org/lkml/2008/10/30/523 and it seems to also recommend
using an older kernel as the branch base.


[PATCH v3 0/2] Last step to working Allwinner R40 pinctrl

2017-07-21 Thread Icenowy Zheng
This patchset contains only two patches.

The first one is a minor fix for the A10 pinctrl driver, add a function
of a pin, which used to be missing in A10/A20 pinctrl driver. Thanks for
Chen-Yu for discovering it when reviewing my R40 pinctrl patchset.

The second one is the real R40 pinctrl part, with fixes suggested by
Chen-Yu and Maxime.

Icenowy Zheng (2):
  pinctrl: sunxi: add a missing function of A10/A20 pinctrl driver
  pinctrl: sunxi: add support of R40 to A10 pinctrl driver

 drivers/pinctrl/sunxi/Kconfig |   2 +-
 drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 274 +-
 2 files changed, 197 insertions(+), 79 deletions(-)

-- 
2.13.0



[PATCH v3 0/2] Last step to working Allwinner R40 pinctrl

2017-07-21 Thread Icenowy Zheng
This patchset contains only two patches.

The first one is a minor fix for the A10 pinctrl driver, add a function
of a pin, which used to be missing in A10/A20 pinctrl driver. Thanks for
Chen-Yu for discovering it when reviewing my R40 pinctrl patchset.

The second one is the real R40 pinctrl part, with fixes suggested by
Chen-Yu and Maxime.

Icenowy Zheng (2):
  pinctrl: sunxi: add a missing function of A10/A20 pinctrl driver
  pinctrl: sunxi: add support of R40 to A10 pinctrl driver

 drivers/pinctrl/sunxi/Kconfig |   2 +-
 drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 274 +-
 2 files changed, 197 insertions(+), 79 deletions(-)

-- 
2.13.0



[PATCH v3 2/2] pinctrl: sunxi: add support of R40 to A10 pinctrl driver

2017-07-21 Thread Icenowy Zheng
R40 is said to be an upgrade of A20, and its pin configuration is also
similar to A20 (and thus similar to A10).

Add support for R40 to the A10 pinctrl driver.

Signed-off-by: Icenowy Zheng 
Reviewed-by: Chen-Yu Tsai 
---
Changes in v3:
- Fixed a missing comma in v2.
- Added Chen-Yu's review tag.
Changes in v2:
- Fixed some lines' format.

 drivers/pinctrl/sunxi/Kconfig |   2 +-
 drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 273 +-
 2 files changed, 196 insertions(+), 79 deletions(-)

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index 31f85ca92669..bfce99d86dfc 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -7,7 +7,7 @@ config PINCTRL_SUNXI
select GPIOLIB
 
 config PINCTRL_SUN4I_A10
-   def_bool MACH_SUN4I || MACH_SUN7I
+   def_bool MACH_SUN4I || MACH_SUN7I || MACH_SUN8I
select PINCTRL_SUNXI
 
 config PINCTRL_SUN5I
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c 
b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
index 47a392bc73c8..f763d8d62d6e 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
@@ -26,7 +26,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
  SUNXI_FUNCTION(0x3, "spi1"),  /* CS0 */
  SUNXI_FUNCTION(0x4, "uart2"), /* RTS */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GRXD3 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
@@ -34,7 +35,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
  SUNXI_FUNCTION(0x3, "spi1"),  /* CLK */
  SUNXI_FUNCTION(0x4, "uart2"), /* CTS */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GRXD2 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
@@ -42,7 +44,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
  SUNXI_FUNCTION(0x3, "spi1"),  /* MOSI */
  SUNXI_FUNCTION(0x4, "uart2"), /* TX */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GRXD1 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
@@ -50,65 +53,75 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
  SUNXI_FUNCTION(0x3, "spi1"),  /* MISO */
  SUNXI_FUNCTION(0x4, "uart2"), /* RX */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GRXD0 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
  SUNXI_FUNCTION(0x2, "emac"),  /* ETXD3 */
  SUNXI_FUNCTION(0x3, "spi1"),  /* CS1 */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GTXD3 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
  SUNXI_FUNCTION(0x2, "emac"),  /* ETXD2 */
  SUNXI_FUNCTION(0x3, "spi3"),  /* CS0 */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GTXD2 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
  SUNXI_FUNCTION(0x2, "emac"),  /* ETXD1 */
  SUNXI_FUNCTION(0x3, "spi3"),  /* CLK */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GTXD1 */
-PINCTRL_SUN7I_A20)),
+   

[PATCH v3 2/2] pinctrl: sunxi: add support of R40 to A10 pinctrl driver

2017-07-21 Thread Icenowy Zheng
R40 is said to be an upgrade of A20, and its pin configuration is also
similar to A20 (and thus similar to A10).

Add support for R40 to the A10 pinctrl driver.

Signed-off-by: Icenowy Zheng 
Reviewed-by: Chen-Yu Tsai 
---
Changes in v3:
- Fixed a missing comma in v2.
- Added Chen-Yu's review tag.
Changes in v2:
- Fixed some lines' format.

 drivers/pinctrl/sunxi/Kconfig |   2 +-
 drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 273 +-
 2 files changed, 196 insertions(+), 79 deletions(-)

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index 31f85ca92669..bfce99d86dfc 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -7,7 +7,7 @@ config PINCTRL_SUNXI
select GPIOLIB
 
 config PINCTRL_SUN4I_A10
-   def_bool MACH_SUN4I || MACH_SUN7I
+   def_bool MACH_SUN4I || MACH_SUN7I || MACH_SUN8I
select PINCTRL_SUNXI
 
 config PINCTRL_SUN5I
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c 
b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
index 47a392bc73c8..f763d8d62d6e 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
@@ -26,7 +26,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
  SUNXI_FUNCTION(0x3, "spi1"),  /* CS0 */
  SUNXI_FUNCTION(0x4, "uart2"), /* RTS */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GRXD3 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
@@ -34,7 +35,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
  SUNXI_FUNCTION(0x3, "spi1"),  /* CLK */
  SUNXI_FUNCTION(0x4, "uart2"), /* CTS */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GRXD2 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
@@ -42,7 +44,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
  SUNXI_FUNCTION(0x3, "spi1"),  /* MOSI */
  SUNXI_FUNCTION(0x4, "uart2"), /* TX */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GRXD1 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
@@ -50,65 +53,75 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
  SUNXI_FUNCTION(0x3, "spi1"),  /* MISO */
  SUNXI_FUNCTION(0x4, "uart2"), /* RX */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GRXD0 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
  SUNXI_FUNCTION(0x2, "emac"),  /* ETXD3 */
  SUNXI_FUNCTION(0x3, "spi1"),  /* CS1 */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GTXD3 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
  SUNXI_FUNCTION(0x2, "emac"),  /* ETXD2 */
  SUNXI_FUNCTION(0x3, "spi3"),  /* CS0 */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GTXD2 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+PINCTRL_SUN8I_R40)),
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
  SUNXI_FUNCTION(0x2, "emac"),  /* ETXD1 */
  SUNXI_FUNCTION(0x3, "spi3"),  /* CLK */
  SUNXI_FUNCTION_VARIANT(0x5, "gmac",   /* GTXD1 */
-PINCTRL_SUN7I_A20)),
+PINCTRL_SUN7I_A20 |
+  

[PATCH v3 1/2] pinctrl: sunxi: add a missing function of A10/A20 pinctrl driver

2017-07-21 Thread Icenowy Zheng
The PH16 pin has a function with mux id 0x5, which is the DET pin of the
"sim" (smart card reader) IP block.

This function is missing in old versions of A10/A20 SoCs' datasheets and
user manuals, so it's also missing in the old drivers. The newest A10
Datasheet V1.70 and A20 Datasheet V1.41 contain this pin function, and
it's discovered during implementing R40 pinctrl driver.

Add it to the driver. As we now merged A20 pinctrl driver to the A10
one, we need to only fix the A10 driver now.

Fixes: f2821b1ca3a2 ("pinctrl: sunxi: Move Allwinner A10 pinctrl
driver to a driver of its own")

Signed-off-by: Icenowy Zheng 
Reviewed-by: Chen-Yu Tsai 
---
Changes in v3:
- Added Chen-Yu's review tag.
- Added fix tag suggested by Chen-Yu.
Changes in v2:
- Commit message changes. (mentioning the datasheet versions which are
  used to discover this pin function.)

 drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c 
b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
index 159580c04b14..47a392bc73c8 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
@@ -918,6 +918,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
  SUNXI_FUNCTION_VARIANT(0x3, "emac",   /* ETXD1 */
 PINCTRL_SUN7I_A20),
  SUNXI_FUNCTION(0x4, "keypad"),/* IN6 */
+ SUNXI_FUNCTION(0x5, "sim"),   /* DET */
  SUNXI_FUNCTION_IRQ(0x6, 16),  /* EINT16 */
  SUNXI_FUNCTION(0x7, "csi1")), /* D16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 17),
-- 
2.13.0



[PATCH v3 1/2] pinctrl: sunxi: add a missing function of A10/A20 pinctrl driver

2017-07-21 Thread Icenowy Zheng
The PH16 pin has a function with mux id 0x5, which is the DET pin of the
"sim" (smart card reader) IP block.

This function is missing in old versions of A10/A20 SoCs' datasheets and
user manuals, so it's also missing in the old drivers. The newest A10
Datasheet V1.70 and A20 Datasheet V1.41 contain this pin function, and
it's discovered during implementing R40 pinctrl driver.

Add it to the driver. As we now merged A20 pinctrl driver to the A10
one, we need to only fix the A10 driver now.

Fixes: f2821b1ca3a2 ("pinctrl: sunxi: Move Allwinner A10 pinctrl
driver to a driver of its own")

Signed-off-by: Icenowy Zheng 
Reviewed-by: Chen-Yu Tsai 
---
Changes in v3:
- Added Chen-Yu's review tag.
- Added fix tag suggested by Chen-Yu.
Changes in v2:
- Commit message changes. (mentioning the datasheet versions which are
  used to discover this pin function.)

 drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c 
b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
index 159580c04b14..47a392bc73c8 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
@@ -918,6 +918,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
  SUNXI_FUNCTION_VARIANT(0x3, "emac",   /* ETXD1 */
 PINCTRL_SUN7I_A20),
  SUNXI_FUNCTION(0x4, "keypad"),/* IN6 */
+ SUNXI_FUNCTION(0x5, "sim"),   /* DET */
  SUNXI_FUNCTION_IRQ(0x6, 16),  /* EINT16 */
  SUNXI_FUNCTION(0x7, "csi1")), /* D16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 17),
-- 
2.13.0



[PATCH 3/3] arm64: allwinner: a64: add ethernet0 alias for SoPine EMAC node

2017-07-21 Thread Icenowy Zheng
The SoPine official baseboard uses the A64 chip's EMAC to provide an
Ethernet link.

Add the ethernet0 alias in the device tree, in order to let U-Boot
generate a MAC address from the chip's SID.

Signed-off-by: Icenowy Zheng 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
index 17eb1cc5bf6b..216e3a5dafae 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
@@ -53,6 +53,7 @@
 "allwinner,sun50i-a64";
 
aliases {
+   ethernet0 = 
serial0 = 
};
 
-- 
2.13.0



[PATCH 3/3] arm64: allwinner: a64: add ethernet0 alias for SoPine EMAC node

2017-07-21 Thread Icenowy Zheng
The SoPine official baseboard uses the A64 chip's EMAC to provide an
Ethernet link.

Add the ethernet0 alias in the device tree, in order to let U-Boot
generate a MAC address from the chip's SID.

Signed-off-by: Icenowy Zheng 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
index 17eb1cc5bf6b..216e3a5dafae 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
@@ -53,6 +53,7 @@
 "allwinner,sun50i-a64";
 
aliases {
+   ethernet0 = 
serial0 = 
};
 
-- 
2.13.0



[PATCH 0/3] Add ethernet0 alias for several A64 boards

2017-07-21 Thread Icenowy Zheng
Allwinner A64 SoC has an EMAC which is used to provide Ethernet
function on several boards.

The EMAC itself doesn't have a fixed MAC address, but the sunxi
mainline U-Boot have the ability to generate one based on the eFUSE
SID in the chip, and add the generated MAC address to the device
tree when booting.

The MAC address setting step is based on the device tree's aliases,
and device tree nodes prefixed "ethernet" will get the MAC address
added. However, in several A64 boards' device tree, the alias is not
set up, so that the U-Boot won't set the MAC address.

Add the ethernet0 aliases to these boards.

I hope this patchset can be queued in 4.13, otherwise 4.13 kernels
won't get non-volatile MAC addresses, and will use random ones
instead, which is annoying to many users.

Icenowy Zheng (3):
  arm64: allwinner: a64: add ethernet0 alias for BPi M64 EMAC node
  arm64: allwinner: a64: add ethernet0 alias for Pine64 EMAC node
  arm64: allwinner: a64: add ethernet0 alias for SoPine EMAC node

 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 1 +
 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts   | 1 +
 arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 1 +
 3 files changed, 3 insertions(+)

-- 
2.13.0



[PATCH 2/3] arm64: allwinner: a64: add ethernet0 alias for Pine64 EMAC node

2017-07-21 Thread Icenowy Zheng
The Pine64 (including the Plus models) board uses the A64 chip's
EMAC to provide Ethernet link.

Add the ethernet0 alias in the device tree, in order to let U-Boot
generate a MAC address from the chip's SID.

Signed-off-by: Icenowy Zheng 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 64cce0d68cae..7a450dcb7a08 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -51,6 +51,7 @@
compatible = "pine64,pine64", "allwinner,sun50i-a64";
 
aliases {
+   ethernet0 = 
serial0 = 
serial1 = 
serial2 = 
-- 
2.13.0



[PATCH 0/3] Add ethernet0 alias for several A64 boards

2017-07-21 Thread Icenowy Zheng
Allwinner A64 SoC has an EMAC which is used to provide Ethernet
function on several boards.

The EMAC itself doesn't have a fixed MAC address, but the sunxi
mainline U-Boot have the ability to generate one based on the eFUSE
SID in the chip, and add the generated MAC address to the device
tree when booting.

The MAC address setting step is based on the device tree's aliases,
and device tree nodes prefixed "ethernet" will get the MAC address
added. However, in several A64 boards' device tree, the alias is not
set up, so that the U-Boot won't set the MAC address.

Add the ethernet0 aliases to these boards.

I hope this patchset can be queued in 4.13, otherwise 4.13 kernels
won't get non-volatile MAC addresses, and will use random ones
instead, which is annoying to many users.

Icenowy Zheng (3):
  arm64: allwinner: a64: add ethernet0 alias for BPi M64 EMAC node
  arm64: allwinner: a64: add ethernet0 alias for Pine64 EMAC node
  arm64: allwinner: a64: add ethernet0 alias for SoPine EMAC node

 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 1 +
 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts   | 1 +
 arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 1 +
 3 files changed, 3 insertions(+)

-- 
2.13.0



[PATCH 2/3] arm64: allwinner: a64: add ethernet0 alias for Pine64 EMAC node

2017-07-21 Thread Icenowy Zheng
The Pine64 (including the Plus models) board uses the A64 chip's
EMAC to provide Ethernet link.

Add the ethernet0 alias in the device tree, in order to let U-Boot
generate a MAC address from the chip's SID.

Signed-off-by: Icenowy Zheng 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 64cce0d68cae..7a450dcb7a08 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -51,6 +51,7 @@
compatible = "pine64,pine64", "allwinner,sun50i-a64";
 
aliases {
+   ethernet0 = 
serial0 = 
serial1 = 
serial2 = 
-- 
2.13.0



[PATCH 1/3] arm64: allwinner: a64: add ethernet0 alias for BPi M64 EMAC node

2017-07-21 Thread Icenowy Zheng
The Banana Pi M64 board uses the A64 chip's EMAC to provide Ethernet
link.

Add the ethernet0 alias in the device tree, in order to let U-Boot
generate a MAC address from the chip's SID.

Signed-off-by: Icenowy Zheng 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
index 0d1f026d831a..ba2fde2909f9 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
@@ -51,6 +51,7 @@
compatible = "sinovoip,bananapi-m64", "allwinner,sun50i-a64";
 
aliases {
+   ethernet0 = 
serial0 = 
serial1 = 
};
-- 
2.13.0



[PATCH 1/3] arm64: allwinner: a64: add ethernet0 alias for BPi M64 EMAC node

2017-07-21 Thread Icenowy Zheng
The Banana Pi M64 board uses the A64 chip's EMAC to provide Ethernet
link.

Add the ethernet0 alias in the device tree, in order to let U-Boot
generate a MAC address from the chip's SID.

Signed-off-by: Icenowy Zheng 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
index 0d1f026d831a..ba2fde2909f9 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
@@ -51,6 +51,7 @@
compatible = "sinovoip,bananapi-m64", "allwinner,sun50i-a64";
 
aliases {
+   ethernet0 = 
serial0 = 
serial1 = 
};
-- 
2.13.0



[PATCH v2 2/2] arm64: allwinner: a64: add AXP803 PMIC support to SoPine and the baseboard

2017-07-21 Thread Icenowy Zheng
The SoPine SoM has an AXP803 PMIC connected to the RSB bus of the A64
SoC, and the regulators of the PMIC are used both on the SoM itself and
on the official baseboard

Add related device tree parts to the SoPine SoM DTSI file and the
baseboard DT.

Signed-off-by: Icenowy Zheng 
---
Changes in v2:
- Squashed AXP803 enabling patch and AXP803 regulators patch together.
- Change the min voltage of vdd-cpux to 1.04V.
- Added constraints for FLDO1 (vcc-1v2-hsic), as it's connected to the SoC
  (although HSIC function is not used).

 .../dts/allwinner/sun50i-a64-sopine-baseboard.dts  | 23 ++
 .../boot/dts/allwinner/sun50i-a64-sopine.dtsi  | 86 ++
 2 files changed, 109 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
index 17eb1cc5bf6b..834a5d249bb2 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
@@ -81,6 +81,7 @@
pinctrl-0 = <_pins>;
phy-mode = "rgmii";
phy-handle = <_rgmii_phy>;
+   phy-supply = <_dc1sw>;
status = "okay";
 };
 
@@ -110,6 +111,28 @@
status = "okay";
 };
 
+_dc1sw {
+   regulator-name = "vcc-phy";
+};
+
+_dldo1 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-hdmi";
+};
+
+_dldo2 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-mipi";
+};
+
+_dldo4 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-wifi";
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
index 475518b031dd..a5da18a6f286 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
@@ -63,3 +63,89 @@
bus-width = <4>;
status = "okay";
 };
+
+_rsb {
+   status = "okay";
+
+   axp803: pmic@3a3 {
+   compatible = "x-powers,axp803";
+   reg = <0x3a3>;
+   interrupt-parent = <_intc>;
+   interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+   };
+};
+
+#include "axp803.dtsi"
+
+_aldo2 {
+   regulator-always-on;
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-pl";
+};
+
+_aldo3 {
+   regulator-always-on;
+   regulator-min-microvolt = <300>;
+   regulator-max-microvolt = <300>;
+   regulator-name = "vcc-pll-avcc";
+};
+
+_dcdc1 {
+   regulator-always-on;
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-3v3";
+};
+
+_dcdc2 {
+   regulator-always-on;
+   regulator-min-microvolt = <104>;
+   regulator-max-microvolt = <130>;
+   regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+_dcdc5 {
+   regulator-always-on;
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <120>;
+   regulator-name = "vcc-dram";
+};
+
+_dcdc6 {
+   regulator-always-on;
+   regulator-min-microvolt = <110>;
+   regulator-max-microvolt = <110>;
+   regulator-name = "vdd-sys";
+};
+
+_eldo1 {
+   regulator-always-on;
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-name = "vdd-1v8-lpddr";
+};
+
+_fldo1 {
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <120>;
+   regulator-name = "vcc-1v2-hsic";
+};
+
+/*
+ * The A64 chip cannot work without this regulator off, although
+ * it seems to be only driving the AR100 core.
+ * Maybe we don't still know well about CPUs domain.
+ */
+_fldo2 {
+   regulator-always-on;
+   regulator-min-microvolt = <110>;
+   regulator-max-microvolt = <110>;
+   regulator-name = "vdd-cpus";
+};
+
+_rtc_ldo {
+   regulator-name = "vcc-rtc";
+};
-- 
2.13.0



[PATCH v2 1/2] arm64: allwinner: a64: enable AXP803 regulators for Pine64

2017-07-21 Thread Icenowy Zheng
Add support of AXP803 regulators in the Pine64 device tree.

The phy-supply regulator is also set in EMAC device node, in order to
prevent Ethernet regression by regulator get disabled by regulator
framework.

Signed-off-by: Icenowy Zheng 
---
Changes in v2:
- Change the min voltage of vdd-cpux to 1.04V.
- Added constraints for FLDO1 (vcc-1v2-hsic), as it's connected to the SoC
  (although HSIC function is not used).

 .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 102 +
 1 file changed, 102 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 64cce0d68cae..2bcf0a3e36b4 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -83,6 +83,7 @@
pinctrl-0 = <_pins>;
phy-mode = "rmii";
phy-handle = <_rmii_phy1>;
+   phy-supply = <_dc1sw>;
status = "okay";
 
 };
@@ -134,6 +135,107 @@
};
 };
 
+#include "axp803.dtsi"
+
+_aldo2 {
+   regulator-always-on;
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-pl";
+};
+
+_aldo3 {
+   regulator-always-on;
+   regulator-min-microvolt = <300>;
+   regulator-max-microvolt = <300>;
+   regulator-name = "vcc-pll-avcc";
+};
+
+_dc1sw {
+   regulator-name = "vcc-phy";
+};
+
+_dcdc1 {
+   regulator-always-on;
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-3v3";
+};
+
+_dcdc2 {
+   regulator-always-on;
+   regulator-min-microvolt = <104>;
+   regulator-max-microvolt = <130>;
+   regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+/*
+ * The DRAM chips used by Pine64 boards are DDR3L-compatible, so they can
+ * work at 1.35V with less power consumption.
+ * As AXP803 DCDC5 cannot reach 1.35V accurately, use 1.36V instead.
+ */
+_dcdc5 {
+   regulator-always-on;
+   regulator-min-microvolt = <136>;
+   regulator-max-microvolt = <136>;
+   regulator-name = "vcc-dram";
+};
+
+_dcdc6 {
+   regulator-always-on;
+   regulator-min-microvolt = <110>;
+   regulator-max-microvolt = <110>;
+   regulator-name = "vdd-sys";
+};
+
+_dldo1 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-hdmi";
+};
+
+_dldo2 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-mipi";
+};
+
+_dldo4 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-wifi";
+};
+
+_eldo1 {
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-name = "cpvdd";
+};
+
+_fldo1 {
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <120>;
+   regulator-name = "vcc-1v2-hsic";
+};
+
+/*
+ * The A64 chip cannot work without this regulator off, although
+ * it seems to be only driving the AR100 core.
+ * Maybe we don't still know well about CPUs domain.
+ */
+_fldo2 {
+   regulator-always-on;
+   regulator-min-microvolt = <110>;
+   regulator-max-microvolt = <110>;
+   regulator-name = "vdd-cpus";
+};
+
+_rtc_ldo {
+   regulator-name = "vcc-rtc";
+};
+
 /* On Exp and Euler connectors */
  {
pinctrl-names = "default";
-- 
2.13.0



[PATCH v2 2/2] arm64: allwinner: a64: add AXP803 PMIC support to SoPine and the baseboard

2017-07-21 Thread Icenowy Zheng
The SoPine SoM has an AXP803 PMIC connected to the RSB bus of the A64
SoC, and the regulators of the PMIC are used both on the SoM itself and
on the official baseboard

Add related device tree parts to the SoPine SoM DTSI file and the
baseboard DT.

Signed-off-by: Icenowy Zheng 
---
Changes in v2:
- Squashed AXP803 enabling patch and AXP803 regulators patch together.
- Change the min voltage of vdd-cpux to 1.04V.
- Added constraints for FLDO1 (vcc-1v2-hsic), as it's connected to the SoC
  (although HSIC function is not used).

 .../dts/allwinner/sun50i-a64-sopine-baseboard.dts  | 23 ++
 .../boot/dts/allwinner/sun50i-a64-sopine.dtsi  | 86 ++
 2 files changed, 109 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
index 17eb1cc5bf6b..834a5d249bb2 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
@@ -81,6 +81,7 @@
pinctrl-0 = <_pins>;
phy-mode = "rgmii";
phy-handle = <_rgmii_phy>;
+   phy-supply = <_dc1sw>;
status = "okay";
 };
 
@@ -110,6 +111,28 @@
status = "okay";
 };
 
+_dc1sw {
+   regulator-name = "vcc-phy";
+};
+
+_dldo1 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-hdmi";
+};
+
+_dldo2 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-mipi";
+};
+
+_dldo4 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-wifi";
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
index 475518b031dd..a5da18a6f286 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
@@ -63,3 +63,89 @@
bus-width = <4>;
status = "okay";
 };
+
+_rsb {
+   status = "okay";
+
+   axp803: pmic@3a3 {
+   compatible = "x-powers,axp803";
+   reg = <0x3a3>;
+   interrupt-parent = <_intc>;
+   interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+   };
+};
+
+#include "axp803.dtsi"
+
+_aldo2 {
+   regulator-always-on;
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-pl";
+};
+
+_aldo3 {
+   regulator-always-on;
+   regulator-min-microvolt = <300>;
+   regulator-max-microvolt = <300>;
+   regulator-name = "vcc-pll-avcc";
+};
+
+_dcdc1 {
+   regulator-always-on;
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-3v3";
+};
+
+_dcdc2 {
+   regulator-always-on;
+   regulator-min-microvolt = <104>;
+   regulator-max-microvolt = <130>;
+   regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+_dcdc5 {
+   regulator-always-on;
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <120>;
+   regulator-name = "vcc-dram";
+};
+
+_dcdc6 {
+   regulator-always-on;
+   regulator-min-microvolt = <110>;
+   regulator-max-microvolt = <110>;
+   regulator-name = "vdd-sys";
+};
+
+_eldo1 {
+   regulator-always-on;
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-name = "vdd-1v8-lpddr";
+};
+
+_fldo1 {
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <120>;
+   regulator-name = "vcc-1v2-hsic";
+};
+
+/*
+ * The A64 chip cannot work without this regulator off, although
+ * it seems to be only driving the AR100 core.
+ * Maybe we don't still know well about CPUs domain.
+ */
+_fldo2 {
+   regulator-always-on;
+   regulator-min-microvolt = <110>;
+   regulator-max-microvolt = <110>;
+   regulator-name = "vdd-cpus";
+};
+
+_rtc_ldo {
+   regulator-name = "vcc-rtc";
+};
-- 
2.13.0



[PATCH v2 1/2] arm64: allwinner: a64: enable AXP803 regulators for Pine64

2017-07-21 Thread Icenowy Zheng
Add support of AXP803 regulators in the Pine64 device tree.

The phy-supply regulator is also set in EMAC device node, in order to
prevent Ethernet regression by regulator get disabled by regulator
framework.

Signed-off-by: Icenowy Zheng 
---
Changes in v2:
- Change the min voltage of vdd-cpux to 1.04V.
- Added constraints for FLDO1 (vcc-1v2-hsic), as it's connected to the SoC
  (although HSIC function is not used).

 .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 102 +
 1 file changed, 102 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 64cce0d68cae..2bcf0a3e36b4 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -83,6 +83,7 @@
pinctrl-0 = <_pins>;
phy-mode = "rmii";
phy-handle = <_rmii_phy1>;
+   phy-supply = <_dc1sw>;
status = "okay";
 
 };
@@ -134,6 +135,107 @@
};
 };
 
+#include "axp803.dtsi"
+
+_aldo2 {
+   regulator-always-on;
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-pl";
+};
+
+_aldo3 {
+   regulator-always-on;
+   regulator-min-microvolt = <300>;
+   regulator-max-microvolt = <300>;
+   regulator-name = "vcc-pll-avcc";
+};
+
+_dc1sw {
+   regulator-name = "vcc-phy";
+};
+
+_dcdc1 {
+   regulator-always-on;
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-3v3";
+};
+
+_dcdc2 {
+   regulator-always-on;
+   regulator-min-microvolt = <104>;
+   regulator-max-microvolt = <130>;
+   regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+/*
+ * The DRAM chips used by Pine64 boards are DDR3L-compatible, so they can
+ * work at 1.35V with less power consumption.
+ * As AXP803 DCDC5 cannot reach 1.35V accurately, use 1.36V instead.
+ */
+_dcdc5 {
+   regulator-always-on;
+   regulator-min-microvolt = <136>;
+   regulator-max-microvolt = <136>;
+   regulator-name = "vcc-dram";
+};
+
+_dcdc6 {
+   regulator-always-on;
+   regulator-min-microvolt = <110>;
+   regulator-max-microvolt = <110>;
+   regulator-name = "vdd-sys";
+};
+
+_dldo1 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-hdmi";
+};
+
+_dldo2 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-mipi";
+};
+
+_dldo4 {
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   regulator-name = "vcc-wifi";
+};
+
+_eldo1 {
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-name = "cpvdd";
+};
+
+_fldo1 {
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <120>;
+   regulator-name = "vcc-1v2-hsic";
+};
+
+/*
+ * The A64 chip cannot work without this regulator off, although
+ * it seems to be only driving the AR100 core.
+ * Maybe we don't still know well about CPUs domain.
+ */
+_fldo2 {
+   regulator-always-on;
+   regulator-min-microvolt = <110>;
+   regulator-max-microvolt = <110>;
+   regulator-name = "vdd-cpus";
+};
+
+_rtc_ldo {
+   regulator-name = "vcc-rtc";
+};
+
 /* On Exp and Euler connectors */
  {
pinctrl-names = "default";
-- 
2.13.0



[PATCH v2 0/2] AXP803 regulators support for Pine64 and SoPine

2017-07-21 Thread Icenowy Zheng
The Pine64 and SoPine w/ baseboard boards have an AXP803 PMIC, and the
regulators of the PMIC are used.

This patchset adds the regulators to the device tree of these two boards.

The first patch is for Pine64 and the second if for SoPine w/ official
baseboard.

The patches that drop the dummy regulators in v1 are removed.

Icenowy Zheng (2):
  arm64: allwinner: a64: enable AXP803 regulators for Pine64
  arm64: allwinner: a64: add AXP803 PMIC support to SoPine and the
baseboard

 .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 102 +
 .../dts/allwinner/sun50i-a64-sopine-baseboard.dts  |  23 +
 .../boot/dts/allwinner/sun50i-a64-sopine.dtsi  |  86 +
 3 files changed, 211 insertions(+)

-- 
2.13.0



[PATCH v2 0/2] AXP803 regulators support for Pine64 and SoPine

2017-07-21 Thread Icenowy Zheng
The Pine64 and SoPine w/ baseboard boards have an AXP803 PMIC, and the
regulators of the PMIC are used.

This patchset adds the regulators to the device tree of these two boards.

The first patch is for Pine64 and the second if for SoPine w/ official
baseboard.

The patches that drop the dummy regulators in v1 are removed.

Icenowy Zheng (2):
  arm64: allwinner: a64: enable AXP803 regulators for Pine64
  arm64: allwinner: a64: add AXP803 PMIC support to SoPine and the
baseboard

 .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 102 +
 .../dts/allwinner/sun50i-a64-sopine-baseboard.dts  |  23 +
 .../boot/dts/allwinner/sun50i-a64-sopine.dtsi  |  86 +
 3 files changed, 211 insertions(+)

-- 
2.13.0



Re: [PATCH Y.A. RESEND] MAINTAINERS: fix alpha. ordering

2017-07-21 Thread Linus Torvalds
On Fri, Jul 21, 2017 at 1:32 PM, Randy Dunlap  wrote:
>
> and send with correct file encoding!

Congratulations, you were indeed successful in fixing whatever locale
issue that was biting you.

  Linus


Re: [PATCH Y.A. RESEND] MAINTAINERS: fix alpha. ordering

2017-07-21 Thread Linus Torvalds
On Fri, Jul 21, 2017 at 1:32 PM, Randy Dunlap  wrote:
>
> and send with correct file encoding!

Congratulations, you were indeed successful in fixing whatever locale
issue that was biting you.

  Linus


[PATCH v2 0/2] x86/amd: Refactor and fixup family17h cpu_core_id

2017-07-21 Thread Suravee Suthikulpanit
Changes from V1 (https://lkml.org/lkml/2017/7/20/180)
  * Refactor topology extension logic into __get_topoext() (per Boris)

Suravee Suthikulpanit (2):
  x86/amd: Refactor topology extension related code
  x86/amd: Fixup cpu_core_id for family17h downcore configuration

 arch/x86/kernel/cpu/amd.c | 108 --
 1 file changed, 76 insertions(+), 32 deletions(-)

-- 
2.7.4



[PATCH v2 2/2] x86/amd: Fixup cpu_core_id for family17h downcore configuration

2017-07-21 Thread Suravee Suthikulpanit
For family17h, current cpu_core_id is directly taken from the value
CPUID_Fn801E_EBX[7:0] (CoreId), which is the physical ID of the
core within a die. However, on system with downcore configuration
(where not all physical cores within a die are available), this could
result in the case where cpu_core_id > (cores_per_node - 1).

Fix up the cpu_core_id by breaking down the bitfields of CoreId,
and calculate relative ID using available topology information.

Signed-off-by: Suravee Suthikulpanit 
---
 arch/x86/kernel/cpu/amd.c | 73 +++
 1 file changed, 54 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 74d8d7c..d2fbfdf 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -301,36 +301,71 @@ static int nearby_node(int apicid)
  */
 static void __get_topoext(struct cpuinfo_x86 *c)
 {
+   u16 l3_nshared = 0;
u32 eax, ebx, ecx, edx;
int cpu = smp_processor_id();
 
+   if (cpuid_edx(0x8006)) {
+   cpuid_count(0x801d, 3, , , , );
+   l3_nshared = ((eax >> 14) & 0xfff) + 1;
+   }
+
cpuid(0x801e, , , , );
 
smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
 
-   if (c->x86 == 0x15)
-   c->cu_id = ebx & 0xff;
-
-   if (c->x86 >= 0x17) {
-   c->cpu_core_id = ebx & 0xff;
-
-   if (smp_num_siblings > 1)
-   c->x86_max_cores /= smp_num_siblings;
-   }
+   switch (c->x86) {
+   case 0x17: {
+   u32 tmp, ccx_offset, cpu_offset;
 
-   /*
-* We may have multiple LLCs if L3 caches exist, so check if we
-* have an L3 cache by looking at the L3 cache CPUID leaf.
-*/
-   if (cpuid_edx(0x8006)) {
-   if (c->x86 == 0x17) {
+   /*
+* In family 17h, the CPUID_Fn801E_EBX[7:0] (CoreId)
+* is non-contiguous in downcore and non-SMT cases.
+* Fixup the cpu_core_id to be contiguous for cores within
+* the die.
+*/
+   tmp = ebx & 0xff;
+   if (smp_num_siblings == 1) {
/*
-* LLC is at the core complex level.
-* Core complex id is ApicId[3].
+* CoreId bit-encoding for SMT-disabled
+* [7:4] : die
+* [3]   : ccx
+* [2:0] : core
 */
-   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+   ccx_offset = ((tmp >> 3) & 1) * l3_nshared;
+   cpu_offset = tmp & 7;
} else {
-   /* LLC is at the node level. */
+   /*
+* CoreId bit-encoding for SMT-enabled
+* [7:3] : die
+* [2]   : ccx
+* [1:0] : core
+*/
+   ccx_offset = ((tmp >> 2) & 1) * l3_nshared /
+  smp_num_siblings;
+   cpu_offset = tmp & 3;
+   c->x86_max_cores /= smp_num_siblings;
+
+   }
+   c->cpu_core_id = ccx_offset + cpu_offset;
+
+   /*
+* Family17h L3 cache (LLC) is at Core Complex (CCX).
+* There could be multiple CCXs in a node.
+* CCX ID is ApicId[3].
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+
+   pr_debug("Fixup coreid:%#x to cpu_core_id:%#x\n",
+tmp, c->cpu_core_id);
+   break;
+   }
+   case 0x15:
+   c->cu_id = ebx & 0xff;
+   /* Follow through */
+   default:
+   /* LLC is default to L3, which generally per-node */
+   if (l3_nshared > 0) {
u8 node_id = ecx & 0xff;
 
per_cpu(cpu_llc_id, cpu) = node_id;
-- 
2.7.4



[PATCH v2 1/2] x86/amd: Refactor topology extension related code

2017-07-21 Thread Suravee Suthikulpanit
Refactoring in preparation for subsequent changes.
There is no functional change.

Signed-off-by: Suravee Suthikulpanit 
---
 arch/x86/kernel/cpu/amd.c | 79 ++-
 1 file changed, 44 insertions(+), 35 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index bb5abe8..74d8d7c 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -297,54 +297,63 @@ static int nearby_node(int apicid)
 #endif
 
 /*
- * Fixup core topology information for
- * (1) AMD multi-node processors
- * Assumption: Number of cores in each internal node is the same.
- * (2) AMD processors supporting compute units
+ * Get topology information via X86_FEATURE_TOPOEXT
  */
-#ifdef CONFIG_SMP
-static void amd_get_topology(struct cpuinfo_x86 *c)
+static void __get_topoext(struct cpuinfo_x86 *c)
 {
-   u8 node_id;
+   u32 eax, ebx, ecx, edx;
int cpu = smp_processor_id();
 
-   /* get information required for multi-node processors */
-   if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
-   u32 eax, ebx, ecx, edx;
+   cpuid(0x801e, , , , );
 
-   cpuid(0x801e, , , , );
+   smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
 
-   node_id  = ecx & 0xff;
-   smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
+   if (c->x86 == 0x15)
+   c->cu_id = ebx & 0xff;
 
-   if (c->x86 == 0x15)
-   c->cu_id = ebx & 0xff;
+   if (c->x86 >= 0x17) {
+   c->cpu_core_id = ebx & 0xff;
 
-   if (c->x86 >= 0x17) {
-   c->cpu_core_id = ebx & 0xff;
+   if (smp_num_siblings > 1)
+   c->x86_max_cores /= smp_num_siblings;
+   }
 
-   if (smp_num_siblings > 1)
-   c->x86_max_cores /= smp_num_siblings;
-   }
+   /*
+* We may have multiple LLCs if L3 caches exist, so check if we
+* have an L3 cache by looking at the L3 cache CPUID leaf.
+*/
+   if (cpuid_edx(0x8006)) {
+   if (c->x86 == 0x17) {
+   /*
+* LLC is at the core complex level.
+* Core complex id is ApicId[3].
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+   } else {
+   /* LLC is at the node level. */
+   u8 node_id = ecx & 0xff;
 
-   /*
-* We may have multiple LLCs if L3 caches exist, so check if we
-* have an L3 cache by looking at the L3 cache CPUID leaf.
-*/
-   if (cpuid_edx(0x8006)) {
-   if (c->x86 == 0x17) {
-   /*
-* LLC is at the core complex level.
-* Core complex id is ApicId[3].
-*/
-   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
-   } else {
-   /* LLC is at the node level. */
-   per_cpu(cpu_llc_id, cpu) = node_id;
-   }
+   per_cpu(cpu_llc_id, cpu) = node_id;
}
+   }
+}
+
+/*
+ * Fixup core topology information for
+ * (1) AMD multi-node processors
+ * Assumption: Number of cores in each internal node is the same.
+ * (2) AMD processors supporting compute units
+ */
+#ifdef CONFIG_SMP
+static void amd_get_topology(struct cpuinfo_x86 *c)
+{
+   /* get information required for multi-node processors */
+   if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
+   __get_topoext(c);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
+   u8 node_id;
u64 value;
+   int cpu = smp_processor_id();
 
rdmsrl(MSR_FAM10H_NODE_ID, value);
node_id = value & 7;
-- 
2.7.4



[PATCH v2 0/2] x86/amd: Refactor and fixup family17h cpu_core_id

2017-07-21 Thread Suravee Suthikulpanit
Changes from V1 (https://lkml.org/lkml/2017/7/20/180)
  * Refactor topology extension logic into __get_topoext() (per Boris)

Suravee Suthikulpanit (2):
  x86/amd: Refactor topology extension related code
  x86/amd: Fixup cpu_core_id for family17h downcore configuration

 arch/x86/kernel/cpu/amd.c | 108 --
 1 file changed, 76 insertions(+), 32 deletions(-)

-- 
2.7.4



[PATCH v2 2/2] x86/amd: Fixup cpu_core_id for family17h downcore configuration

2017-07-21 Thread Suravee Suthikulpanit
For family17h, current cpu_core_id is directly taken from the value
CPUID_Fn801E_EBX[7:0] (CoreId), which is the physical ID of the
core within a die. However, on system with downcore configuration
(where not all physical cores within a die are available), this could
result in the case where cpu_core_id > (cores_per_node - 1).

Fix up the cpu_core_id by breaking down the bitfields of CoreId,
and calculate relative ID using available topology information.

Signed-off-by: Suravee Suthikulpanit 
---
 arch/x86/kernel/cpu/amd.c | 73 +++
 1 file changed, 54 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 74d8d7c..d2fbfdf 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -301,36 +301,71 @@ static int nearby_node(int apicid)
  */
 static void __get_topoext(struct cpuinfo_x86 *c)
 {
+   u16 l3_nshared = 0;
u32 eax, ebx, ecx, edx;
int cpu = smp_processor_id();
 
+   if (cpuid_edx(0x8006)) {
+   cpuid_count(0x801d, 3, , , , );
+   l3_nshared = ((eax >> 14) & 0xfff) + 1;
+   }
+
cpuid(0x801e, , , , );
 
smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
 
-   if (c->x86 == 0x15)
-   c->cu_id = ebx & 0xff;
-
-   if (c->x86 >= 0x17) {
-   c->cpu_core_id = ebx & 0xff;
-
-   if (smp_num_siblings > 1)
-   c->x86_max_cores /= smp_num_siblings;
-   }
+   switch (c->x86) {
+   case 0x17: {
+   u32 tmp, ccx_offset, cpu_offset;
 
-   /*
-* We may have multiple LLCs if L3 caches exist, so check if we
-* have an L3 cache by looking at the L3 cache CPUID leaf.
-*/
-   if (cpuid_edx(0x8006)) {
-   if (c->x86 == 0x17) {
+   /*
+* In family 17h, the CPUID_Fn801E_EBX[7:0] (CoreId)
+* is non-contiguous in downcore and non-SMT cases.
+* Fixup the cpu_core_id to be contiguous for cores within
+* the die.
+*/
+   tmp = ebx & 0xff;
+   if (smp_num_siblings == 1) {
/*
-* LLC is at the core complex level.
-* Core complex id is ApicId[3].
+* CoreId bit-encoding for SMT-disabled
+* [7:4] : die
+* [3]   : ccx
+* [2:0] : core
 */
-   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+   ccx_offset = ((tmp >> 3) & 1) * l3_nshared;
+   cpu_offset = tmp & 7;
} else {
-   /* LLC is at the node level. */
+   /*
+* CoreId bit-encoding for SMT-enabled
+* [7:3] : die
+* [2]   : ccx
+* [1:0] : core
+*/
+   ccx_offset = ((tmp >> 2) & 1) * l3_nshared /
+  smp_num_siblings;
+   cpu_offset = tmp & 3;
+   c->x86_max_cores /= smp_num_siblings;
+
+   }
+   c->cpu_core_id = ccx_offset + cpu_offset;
+
+   /*
+* Family17h L3 cache (LLC) is at Core Complex (CCX).
+* There could be multiple CCXs in a node.
+* CCX ID is ApicId[3].
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+
+   pr_debug("Fixup coreid:%#x to cpu_core_id:%#x\n",
+tmp, c->cpu_core_id);
+   break;
+   }
+   case 0x15:
+   c->cu_id = ebx & 0xff;
+   /* Follow through */
+   default:
+   /* LLC is default to L3, which generally per-node */
+   if (l3_nshared > 0) {
u8 node_id = ecx & 0xff;
 
per_cpu(cpu_llc_id, cpu) = node_id;
-- 
2.7.4



[PATCH v2 1/2] x86/amd: Refactor topology extension related code

2017-07-21 Thread Suravee Suthikulpanit
Refactoring in preparation for subsequent changes.
There is no functional change.

Signed-off-by: Suravee Suthikulpanit 
---
 arch/x86/kernel/cpu/amd.c | 79 ++-
 1 file changed, 44 insertions(+), 35 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index bb5abe8..74d8d7c 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -297,54 +297,63 @@ static int nearby_node(int apicid)
 #endif
 
 /*
- * Fixup core topology information for
- * (1) AMD multi-node processors
- * Assumption: Number of cores in each internal node is the same.
- * (2) AMD processors supporting compute units
+ * Get topology information via X86_FEATURE_TOPOEXT
  */
-#ifdef CONFIG_SMP
-static void amd_get_topology(struct cpuinfo_x86 *c)
+static void __get_topoext(struct cpuinfo_x86 *c)
 {
-   u8 node_id;
+   u32 eax, ebx, ecx, edx;
int cpu = smp_processor_id();
 
-   /* get information required for multi-node processors */
-   if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
-   u32 eax, ebx, ecx, edx;
+   cpuid(0x801e, , , , );
 
-   cpuid(0x801e, , , , );
+   smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
 
-   node_id  = ecx & 0xff;
-   smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
+   if (c->x86 == 0x15)
+   c->cu_id = ebx & 0xff;
 
-   if (c->x86 == 0x15)
-   c->cu_id = ebx & 0xff;
+   if (c->x86 >= 0x17) {
+   c->cpu_core_id = ebx & 0xff;
 
-   if (c->x86 >= 0x17) {
-   c->cpu_core_id = ebx & 0xff;
+   if (smp_num_siblings > 1)
+   c->x86_max_cores /= smp_num_siblings;
+   }
 
-   if (smp_num_siblings > 1)
-   c->x86_max_cores /= smp_num_siblings;
-   }
+   /*
+* We may have multiple LLCs if L3 caches exist, so check if we
+* have an L3 cache by looking at the L3 cache CPUID leaf.
+*/
+   if (cpuid_edx(0x8006)) {
+   if (c->x86 == 0x17) {
+   /*
+* LLC is at the core complex level.
+* Core complex id is ApicId[3].
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+   } else {
+   /* LLC is at the node level. */
+   u8 node_id = ecx & 0xff;
 
-   /*
-* We may have multiple LLCs if L3 caches exist, so check if we
-* have an L3 cache by looking at the L3 cache CPUID leaf.
-*/
-   if (cpuid_edx(0x8006)) {
-   if (c->x86 == 0x17) {
-   /*
-* LLC is at the core complex level.
-* Core complex id is ApicId[3].
-*/
-   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
-   } else {
-   /* LLC is at the node level. */
-   per_cpu(cpu_llc_id, cpu) = node_id;
-   }
+   per_cpu(cpu_llc_id, cpu) = node_id;
}
+   }
+}
+
+/*
+ * Fixup core topology information for
+ * (1) AMD multi-node processors
+ * Assumption: Number of cores in each internal node is the same.
+ * (2) AMD processors supporting compute units
+ */
+#ifdef CONFIG_SMP
+static void amd_get_topology(struct cpuinfo_x86 *c)
+{
+   /* get information required for multi-node processors */
+   if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
+   __get_topoext(c);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
+   u8 node_id;
u64 value;
+   int cpu = smp_processor_id();
 
rdmsrl(MSR_FAM10H_NODE_ID, value);
node_id = value & 7;
-- 
2.7.4



Re: [PATCH v3 4/5] ACPI / boot: Not all platform require acpi_reduced_hw_init()

2017-07-21 Thread Andy Shevchenko
On Sat, Jul 22, 2017 at 1:25 AM, Rafael J. Wysocki  wrote:
> On Tuesday, July 18, 2017 06:04:19 PM Andy Shevchenko wrote:
>> Some platform might take care of legacy devices on theirs own.
>> Let's allow them to do that by exporting a weak function.
>>
>> Signed-off-by: Andy Shevchenko 
>
> I'd rather do it at the time when acpi_reduced_hw_init() actually needs to be
> overridden by at least one platform.

Do you mean as folded into some other patch or just as a preparatory
patch in some future series?

-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v3 4/5] ACPI / boot: Not all platform require acpi_reduced_hw_init()

2017-07-21 Thread Andy Shevchenko
On Sat, Jul 22, 2017 at 1:25 AM, Rafael J. Wysocki  wrote:
> On Tuesday, July 18, 2017 06:04:19 PM Andy Shevchenko wrote:
>> Some platform might take care of legacy devices on theirs own.
>> Let's allow them to do that by exporting a weak function.
>>
>> Signed-off-by: Andy Shevchenko 
>
> I'd rather do it at the time when acpi_reduced_hw_init() actually needs to be
> overridden by at least one platform.

Do you mean as folded into some other patch or just as a preparatory
patch in some future series?

-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v3 5/5] ACPI / boot: Don't handle SCI on HW reduced platforms

2017-07-21 Thread Andy Shevchenko
On Sat, Jul 22, 2017 at 1:28 AM, Rafael J. Wysocki  wrote:
> On Tuesday, July 18, 2017 06:04:20 PM Andy Shevchenko wrote:
>> As per note in 5.2.9 Fixed ACPI Description Table (FADT) chapter of ACPI
>> specification OSPM will ignore fields related to the ACPI HW register
>> interface, one of which is SCI_INT.
>>
>> Follow the spec and ignore any configuration done for interrupt line
>> defined by SCI_INT if FADT specifies HW reduced platform.

> Can we invalidate acpi_gbl_FADT.sci_interrupt somehow for
> acpi_gbl_reduced_hardware?

At some point there INVALID_ACPI_IRQ is used. There is also helper to
check it acpi_sci_irq_valid().

So, we can use that helper instead.

> The checks added below look somewhat arbitrary and it would be good to
> provide some argumentation on why everything is covered by them as needed.


-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v3 5/5] ACPI / boot: Don't handle SCI on HW reduced platforms

2017-07-21 Thread Andy Shevchenko
On Sat, Jul 22, 2017 at 1:28 AM, Rafael J. Wysocki  wrote:
> On Tuesday, July 18, 2017 06:04:20 PM Andy Shevchenko wrote:
>> As per note in 5.2.9 Fixed ACPI Description Table (FADT) chapter of ACPI
>> specification OSPM will ignore fields related to the ACPI HW register
>> interface, one of which is SCI_INT.
>>
>> Follow the spec and ignore any configuration done for interrupt line
>> defined by SCI_INT if FADT specifies HW reduced platform.

> Can we invalidate acpi_gbl_FADT.sci_interrupt somehow for
> acpi_gbl_reduced_hardware?

At some point there INVALID_ACPI_IRQ is used. There is also helper to
check it acpi_sci_irq_valid().

So, we can use that helper instead.

> The checks added below look somewhat arbitrary and it would be good to
> provide some argumentation on why everything is covered by them as needed.


-- 
With Best Regards,
Andy Shevchenko


[PATCH] Bluetooth: Style fix - align block comments

2017-07-21 Thread Derek Robson
Fixed alignment of all block comments.
Found using checkpatch

Signed-off-by: Derek Robson 
---
 drivers/bluetooth/ath3k.c   |  3 ++-
 drivers/bluetooth/bt3c_cs.c |  8 +---
 drivers/bluetooth/btmrvl_sdio.c |  6 --
 drivers/bluetooth/btsdio.c  |  3 ++-
 drivers/bluetooth/btuart_cs.c   |  8 +---
 drivers/bluetooth/btusb.c   | 15 ++-
 drivers/bluetooth/btwilink.c|  6 +++---
 drivers/bluetooth/hci_ldisc.c   |  3 ++-
 drivers/bluetooth/hci_ll.c  |  3 ++-
 9 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index b793853ff05f..204afe66de92 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -140,7 +140,8 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
 
 #define BTUSB_ATH3012  0x80
 /* This table is to load patch and sysconfig files
- * for AR3012 */
+ * for AR3012
+ */
 static const struct usb_device_id ath3k_blist_tbl[] = {
 
/* Atheros AR3012 with sflash firmware*/
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 32dcac017395..194788739a83 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -684,14 +684,16 @@ static int bt3c_config(struct pcmcia_device *link)
unsigned long try;
 
/* First pass: look for a config entry that looks normal.
-  Two tries: without IO aliases, then with aliases */
+* Two tries: without IO aliases, then with aliases
+*/
for (try = 0; try < 2; try++)
if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
goto found_port;
 
/* Second pass: try to find an entry that isn't picky about
-  its base address, then try to grab any standard serial port
-  address, and finally try to get any free port. */
+* its base address, then try to grab any standard serial port
+* address, and finally try to get any free port.
+*/
if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
goto found_port;
 
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index eb794f08b238..03341ce98c32 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -1455,7 +1455,8 @@ static void btmrvl_sdio_dump_firmware(struct 
btmrvl_private *priv)
fw_dump_ptr = fw_dump_data;
 
/* Dump all the memory data into single file, a userspace script will
-  be used to split all the memory data to multiple files*/
+* be used to split all the memory data to multiple files
+*/
BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump start");
for (idx = 0; idx < dump_num; idx++) {
struct memory_type_mapping *entry = _type_mapping_tbl[idx];
@@ -1482,7 +1483,8 @@ static void btmrvl_sdio_dump_firmware(struct 
btmrvl_private *priv)
}
 
/* fw_dump_data will be free in device coredump release function
-  after 5 min*/
+* after 5 min
+*/
dev_coredumpv(>func->dev, fw_dump_data, fw_dump_len, GFP_KERNEL);
BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump end");
 }
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
index 1cb958e199eb..c8e945d19ffe 100644
--- a/drivers/bluetooth/btsdio.c
+++ b/drivers/bluetooth/btsdio.c
@@ -144,7 +144,8 @@ static int btsdio_rx_packet(struct btsdio_data *data)
if (!skb) {
/* Out of memory. Prepare a read retry and just
 * return with the expectation that the next time
-* we're called we'll have more memory. */
+* we're called we'll have more memory.
+*/
return -ENOMEM;
}
 
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 7df79bb12350..310e9c2e09b6 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -614,14 +614,16 @@ static int btuart_config(struct pcmcia_device *link)
int try;
 
/* First pass: look for a config entry that looks normal.
-  Two tries: without IO aliases, then with aliases */
+* Two tries: without IO aliases, then with aliases
+*/
for (try = 0; try < 2; try++)
if (!pcmcia_loop_config(link, btuart_check_config, ))
goto found_port;
 
/* Second pass: try to find an entry that isn't picky about
-  its base address, then try to grab any standard serial port
-  address, and finally try to get any free port. */
+* its base address, then try to grab any standard serial port
+* address, and finally try to get any free port.
+*/
if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL))
goto found_port;
 
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c

[PATCH] Bluetooth: Style fix - align block comments

2017-07-21 Thread Derek Robson
Fixed alignment of all block comments.
Found using checkpatch

Signed-off-by: Derek Robson 
---
 drivers/bluetooth/ath3k.c   |  3 ++-
 drivers/bluetooth/bt3c_cs.c |  8 +---
 drivers/bluetooth/btmrvl_sdio.c |  6 --
 drivers/bluetooth/btsdio.c  |  3 ++-
 drivers/bluetooth/btuart_cs.c   |  8 +---
 drivers/bluetooth/btusb.c   | 15 ++-
 drivers/bluetooth/btwilink.c|  6 +++---
 drivers/bluetooth/hci_ldisc.c   |  3 ++-
 drivers/bluetooth/hci_ll.c  |  3 ++-
 9 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index b793853ff05f..204afe66de92 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -140,7 +140,8 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
 
 #define BTUSB_ATH3012  0x80
 /* This table is to load patch and sysconfig files
- * for AR3012 */
+ * for AR3012
+ */
 static const struct usb_device_id ath3k_blist_tbl[] = {
 
/* Atheros AR3012 with sflash firmware*/
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 32dcac017395..194788739a83 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -684,14 +684,16 @@ static int bt3c_config(struct pcmcia_device *link)
unsigned long try;
 
/* First pass: look for a config entry that looks normal.
-  Two tries: without IO aliases, then with aliases */
+* Two tries: without IO aliases, then with aliases
+*/
for (try = 0; try < 2; try++)
if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
goto found_port;
 
/* Second pass: try to find an entry that isn't picky about
-  its base address, then try to grab any standard serial port
-  address, and finally try to get any free port. */
+* its base address, then try to grab any standard serial port
+* address, and finally try to get any free port.
+*/
if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
goto found_port;
 
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index eb794f08b238..03341ce98c32 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -1455,7 +1455,8 @@ static void btmrvl_sdio_dump_firmware(struct 
btmrvl_private *priv)
fw_dump_ptr = fw_dump_data;
 
/* Dump all the memory data into single file, a userspace script will
-  be used to split all the memory data to multiple files*/
+* be used to split all the memory data to multiple files
+*/
BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump start");
for (idx = 0; idx < dump_num; idx++) {
struct memory_type_mapping *entry = _type_mapping_tbl[idx];
@@ -1482,7 +1483,8 @@ static void btmrvl_sdio_dump_firmware(struct 
btmrvl_private *priv)
}
 
/* fw_dump_data will be free in device coredump release function
-  after 5 min*/
+* after 5 min
+*/
dev_coredumpv(>func->dev, fw_dump_data, fw_dump_len, GFP_KERNEL);
BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump end");
 }
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
index 1cb958e199eb..c8e945d19ffe 100644
--- a/drivers/bluetooth/btsdio.c
+++ b/drivers/bluetooth/btsdio.c
@@ -144,7 +144,8 @@ static int btsdio_rx_packet(struct btsdio_data *data)
if (!skb) {
/* Out of memory. Prepare a read retry and just
 * return with the expectation that the next time
-* we're called we'll have more memory. */
+* we're called we'll have more memory.
+*/
return -ENOMEM;
}
 
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 7df79bb12350..310e9c2e09b6 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -614,14 +614,16 @@ static int btuart_config(struct pcmcia_device *link)
int try;
 
/* First pass: look for a config entry that looks normal.
-  Two tries: without IO aliases, then with aliases */
+* Two tries: without IO aliases, then with aliases
+*/
for (try = 0; try < 2; try++)
if (!pcmcia_loop_config(link, btuart_check_config, ))
goto found_port;
 
/* Second pass: try to find an entry that isn't picky about
-  its base address, then try to grab any standard serial port
-  address, and finally try to get any free port. */
+* its base address, then try to grab any standard serial port
+* address, and finally try to get any free port.
+*/
if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL))
goto found_port;
 
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 

Re: [PATCH 0/3] Keystone defconfig updates

2017-07-21 Thread Santosh Shilimkar

On 7/17/2017 9:45 PM, santosh.shilim...@oracle.com wrote:



On 7/17/17 8:26 PM, Suman Anna wrote:

Hi Santosh,

The following patch series adds the necessary defconfig options to
keystone_defconfig to enable the TI-SCI protocol and their respective
genpd/clock/reset drivers.

This is the first of two series that provides a baseline for adding
and/or enabling other peripherals on the 66AK2G platforms. Patches are
baselined on 4.13-rc1 and are intended for the 4.14 merge window.


Looks good. Will add this to 4.14 queue and push it to next by
weekend.

The changes should start showing up in linux next. Do let me know if I 
have missed any patches.


Regards,
Santosh


Re: [PATCH 0/3] Keystone defconfig updates

2017-07-21 Thread Santosh Shilimkar

On 7/17/2017 9:45 PM, santosh.shilim...@oracle.com wrote:



On 7/17/17 8:26 PM, Suman Anna wrote:

Hi Santosh,

The following patch series adds the necessary defconfig options to
keystone_defconfig to enable the TI-SCI protocol and their respective
genpd/clock/reset drivers.

This is the first of two series that provides a baseline for adding
and/or enabling other peripherals on the 66AK2G platforms. Patches are
baselined on 4.13-rc1 and are intended for the 4.14 merge window.


Looks good. Will add this to 4.14 queue and push it to next by
weekend.

The changes should start showing up in linux next. Do let me know if I 
have missed any patches.


Regards,
Santosh


[PATCH v2] f2fs: make background threads of f2fs being aware of freezing

2017-07-21 Thread Chao Yu
From: Chao Yu 

When ->freeze_fs is called from lvm for doing snapshot, it needs to
make sure there will be no more changes in filesystem's data, however,
previously, background threads like GC thread wasn't aware of freezing,
so in environment with active background threads, data of snapshot
becomes unstable.

This patch fixes this issue by adding sb_{start,end}_intwrite in
below background threads:
- GC thread
- flush thread
- discard thread

Signed-off-by: Chao Yu 
---
 fs/f2fs/gc.c  | 8 ++--
 fs/f2fs/segment.c | 8 
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 29f412d7cbf1..7aa17f80fdf1 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -55,6 +55,8 @@ static int gc_thread_func(void *data)
}
 #endif
 
+   sb_start_intwrite(sbi->sb);
+
/*
 * [GC triggering condition]
 * 0. GC is not conducted currently.
@@ -69,12 +71,12 @@ static int gc_thread_func(void *data)
 * So, I'd like to wait some time to collect dirty segments.
 */
if (!mutex_trylock(>gc_mutex))
-   continue;
+   goto next;
 
if (!is_idle(sbi)) {
increase_sleep_time(gc_th, _ms);
mutex_unlock(>gc_mutex);
-   continue;
+   goto next;
}
 
if (has_enough_invalid_blocks(sbi))
@@ -93,6 +95,8 @@ static int gc_thread_func(void *data)
 
/* balancing f2fs's metadata periodically */
f2fs_balance_fs_bg(sbi);
+next:
+   sb_end_intwrite(sbi->sb);
 
} while (!kthread_should_stop());
return 0;
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 6d091c75aa59..df1bb0c144f1 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -485,6 +485,8 @@ static int issue_flush_thread(void *data)
if (kthread_should_stop())
return 0;
 
+   sb_start_intwrite(sbi->sb);
+
if (!llist_empty(>issue_list)) {
struct flush_cmd *cmd, *next;
int ret;
@@ -503,6 +505,8 @@ static int issue_flush_thread(void *data)
fcc->dispatch_list = NULL;
}
 
+   sb_end_intwrite(sbi->sb);
+
wait_event_interruptible(*q,
kthread_should_stop() || !llist_empty(>issue_list));
goto repeat;
@@ -1130,9 +1134,13 @@ static int issue_discard_thread(void *data)
if (kthread_should_stop())
return 0;
 
+   sb_start_intwrite(sbi->sb);
+
__issue_discard_cmd(sbi, true);
__wait_discard_cmd(sbi, true);
 
+   sb_end_intwrite(sbi->sb);
+
congestion_wait(BLK_RW_SYNC, HZ/50);
} while (!kthread_should_stop());
return 0;
-- 
2.13.0.90.g1eb437020



[PATCH v2] f2fs: make background threads of f2fs being aware of freezing

2017-07-21 Thread Chao Yu
From: Chao Yu 

When ->freeze_fs is called from lvm for doing snapshot, it needs to
make sure there will be no more changes in filesystem's data, however,
previously, background threads like GC thread wasn't aware of freezing,
so in environment with active background threads, data of snapshot
becomes unstable.

This patch fixes this issue by adding sb_{start,end}_intwrite in
below background threads:
- GC thread
- flush thread
- discard thread

Signed-off-by: Chao Yu 
---
 fs/f2fs/gc.c  | 8 ++--
 fs/f2fs/segment.c | 8 
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 29f412d7cbf1..7aa17f80fdf1 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -55,6 +55,8 @@ static int gc_thread_func(void *data)
}
 #endif
 
+   sb_start_intwrite(sbi->sb);
+
/*
 * [GC triggering condition]
 * 0. GC is not conducted currently.
@@ -69,12 +71,12 @@ static int gc_thread_func(void *data)
 * So, I'd like to wait some time to collect dirty segments.
 */
if (!mutex_trylock(>gc_mutex))
-   continue;
+   goto next;
 
if (!is_idle(sbi)) {
increase_sleep_time(gc_th, _ms);
mutex_unlock(>gc_mutex);
-   continue;
+   goto next;
}
 
if (has_enough_invalid_blocks(sbi))
@@ -93,6 +95,8 @@ static int gc_thread_func(void *data)
 
/* balancing f2fs's metadata periodically */
f2fs_balance_fs_bg(sbi);
+next:
+   sb_end_intwrite(sbi->sb);
 
} while (!kthread_should_stop());
return 0;
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 6d091c75aa59..df1bb0c144f1 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -485,6 +485,8 @@ static int issue_flush_thread(void *data)
if (kthread_should_stop())
return 0;
 
+   sb_start_intwrite(sbi->sb);
+
if (!llist_empty(>issue_list)) {
struct flush_cmd *cmd, *next;
int ret;
@@ -503,6 +505,8 @@ static int issue_flush_thread(void *data)
fcc->dispatch_list = NULL;
}
 
+   sb_end_intwrite(sbi->sb);
+
wait_event_interruptible(*q,
kthread_should_stop() || !llist_empty(>issue_list));
goto repeat;
@@ -1130,9 +1134,13 @@ static int issue_discard_thread(void *data)
if (kthread_should_stop())
return 0;
 
+   sb_start_intwrite(sbi->sb);
+
__issue_discard_cmd(sbi, true);
__wait_discard_cmd(sbi, true);
 
+   sb_end_intwrite(sbi->sb);
+
congestion_wait(BLK_RW_SYNC, HZ/50);
} while (!kthread_should_stop());
return 0;
-- 
2.13.0.90.g1eb437020



Re: 4.12.0: igb: transmit queue 7 timed out

2017-07-21 Thread Cong Wang
(Cc netdev and Intel)

On Tue, Jul 18, 2017 at 1:57 PM, Justin Piszcz  wrote:
> Hello,
>
> Kernel: 4.12.0
> Arch: x86_64
>
> What causes this issue?


It is likely a igb driver issue.


>
> [199141.434449] NETDEV WATCHDOG: eth1 (igb): transmit queue 7 timed out
> [199141.434501] [ cut here ]
> [199141.434515] WARNING: CPU: 10 PID: 0 at net/sched/sch_generic.c:316
> dev_watchdog+0x212/0x220
> [199141.434528] CPU: 10 PID: 0 Comm: swapper/10 Not tainted 4.12.0 #3
> [199141.434533] Hardware name: Supermicro X9SRL-F/X9SRL-F, BIOS 3.2
> 01/16/2015
> [199141.434539] task: 8810385b8180 task.stack: c90b4000
> [199141.434546] RIP: 0010:dev_watchdog+0x212/0x220
> [199141.434551] RSP: 0018:88103f483e68 EFLAGS: 00010286
> [199141.434558] RAX: 0037 RBX: 0007 RCX:
> 083f
> [199141.434563] RDX:  RSI: 00f6 RDI:
> 003f
> [199141.434569] RBP: 88103f483e88 R08: 0006a111 R09:
> 0487
> [199141.434574] R10: 0082 R11: 823f49ee R12:
> 8810348a8000
> [199141.434579] R13: 000a R14: 0008 R15:
> 0082
> [199141.434585] FS:  () GS:88103f48()
> knlGS:
> [199141.434590] CS:  0010 DS:  ES:  CR0: 80050033
> [199141.434596] CR2: 29e25c35b000 CR3: 0220a000 CR4:
> 001406e0
> [199141.434600] Call Trace:
> [199141.434607]  
> [199141.434615]  ? qdisc_rcu_free+0x40/0x40
> [199141.434625]  call_timer_fn.isra.4+0x19/0x90
> [199141.434633]  expire_timers+0x7f/0x90
> [199141.434641]  run_timer_softirq+0x84/0xe0
> [199141.434650]  ? ktime_get+0x3b/0x90
> [199141.434659]  ? clockevents_program_event+0x75/0xf0
> [199141.434666]  __do_softirq+0xdf/0x1f0
> [199141.434673]  irq_exit+0xab/0xb0
> [199141.434681]  smp_trace_apic_timer_interrupt+0x63/0x90
> [199141.434688]  smp_apic_timer_interrupt+0x9/0x10
> [199141.434696]  apic_timer_interrupt+0x86/0x90
> [199141.434705] RIP: 0010:cpuidle_enter_state+0x153/0x1e0
> [199141.434711] RSP: 0018:c90b7e68 EFLAGS: 0286 ORIG_RAX:
> ff10
> [199141.434720] RAX: 88103f499000 RBX: e8c91fd0 RCX:
> 001f
> [199141.434725] RDX: 20c49ba5e353f7cf RSI: 88103f496818 RDI:
> 
> [199141.434730] RBP: c90b7e98 R08: 3f7b R09:
> 0018
> [199141.434735] R10: c90b7e48 R11: 38b6 R12:
> b51e3a7582f1
> [199141.434740] R13: 0004 R14: 8225e2b8 R15:
> 8225e120
> [199141.434746]  
> [199141.434754]  ? cpuidle_enter_state+0x148/0x1e0
> [199141.434762]  cpuidle_enter+0x12/0x20
> [199141.434771]  call_cpuidle+0x1e/0x30
> [199141.434779]  do_idle+0xde/0x180
> [199141.434788]  cpu_startup_entry+0x6c/0x70
> [199141.434796]  start_secondary+0x13c/0x160
> [199141.434808]  secondary_startup_64+0x9f/0x9f
> [199141.434813] Code: 8c 24 a4 03 00 00 eb 8d 4c 89 e7 c6 05 ea 96 81 00 01
> e8 02 f0 fd ff 89 d9 4c 89 e6 48 c7 c7 f0 49 00 82 48 89 c2 e8 bd 08 6e ff
> <0f> ff eb c1 66 2e 0f 1f 84 00 00 00 00 00 48 8b 4e 48 55 44 8b
> [199141.434895] ---[ end trace 0bac15bcef84778a ]---
> [199141.435208] igb :08:00.2 eth1: Reset adapter
> [199144.839995] igb :08:00.2 eth1: igb: eth1 NIC Link is Up 1000 Mbps
> Full Duplex, Flow Control: RX/TX
>
> Justin.
>


Re: 4.12.0: igb: transmit queue 7 timed out

2017-07-21 Thread Cong Wang
(Cc netdev and Intel)

On Tue, Jul 18, 2017 at 1:57 PM, Justin Piszcz  wrote:
> Hello,
>
> Kernel: 4.12.0
> Arch: x86_64
>
> What causes this issue?


It is likely a igb driver issue.


>
> [199141.434449] NETDEV WATCHDOG: eth1 (igb): transmit queue 7 timed out
> [199141.434501] [ cut here ]
> [199141.434515] WARNING: CPU: 10 PID: 0 at net/sched/sch_generic.c:316
> dev_watchdog+0x212/0x220
> [199141.434528] CPU: 10 PID: 0 Comm: swapper/10 Not tainted 4.12.0 #3
> [199141.434533] Hardware name: Supermicro X9SRL-F/X9SRL-F, BIOS 3.2
> 01/16/2015
> [199141.434539] task: 8810385b8180 task.stack: c90b4000
> [199141.434546] RIP: 0010:dev_watchdog+0x212/0x220
> [199141.434551] RSP: 0018:88103f483e68 EFLAGS: 00010286
> [199141.434558] RAX: 0037 RBX: 0007 RCX:
> 083f
> [199141.434563] RDX:  RSI: 00f6 RDI:
> 003f
> [199141.434569] RBP: 88103f483e88 R08: 0006a111 R09:
> 0487
> [199141.434574] R10: 0082 R11: 823f49ee R12:
> 8810348a8000
> [199141.434579] R13: 000a R14: 0008 R15:
> 0082
> [199141.434585] FS:  () GS:88103f48()
> knlGS:
> [199141.434590] CS:  0010 DS:  ES:  CR0: 80050033
> [199141.434596] CR2: 29e25c35b000 CR3: 0220a000 CR4:
> 001406e0
> [199141.434600] Call Trace:
> [199141.434607]  
> [199141.434615]  ? qdisc_rcu_free+0x40/0x40
> [199141.434625]  call_timer_fn.isra.4+0x19/0x90
> [199141.434633]  expire_timers+0x7f/0x90
> [199141.434641]  run_timer_softirq+0x84/0xe0
> [199141.434650]  ? ktime_get+0x3b/0x90
> [199141.434659]  ? clockevents_program_event+0x75/0xf0
> [199141.434666]  __do_softirq+0xdf/0x1f0
> [199141.434673]  irq_exit+0xab/0xb0
> [199141.434681]  smp_trace_apic_timer_interrupt+0x63/0x90
> [199141.434688]  smp_apic_timer_interrupt+0x9/0x10
> [199141.434696]  apic_timer_interrupt+0x86/0x90
> [199141.434705] RIP: 0010:cpuidle_enter_state+0x153/0x1e0
> [199141.434711] RSP: 0018:c90b7e68 EFLAGS: 0286 ORIG_RAX:
> ff10
> [199141.434720] RAX: 88103f499000 RBX: e8c91fd0 RCX:
> 001f
> [199141.434725] RDX: 20c49ba5e353f7cf RSI: 88103f496818 RDI:
> 
> [199141.434730] RBP: c90b7e98 R08: 3f7b R09:
> 0018
> [199141.434735] R10: c90b7e48 R11: 38b6 R12:
> b51e3a7582f1
> [199141.434740] R13: 0004 R14: 8225e2b8 R15:
> 8225e120
> [199141.434746]  
> [199141.434754]  ? cpuidle_enter_state+0x148/0x1e0
> [199141.434762]  cpuidle_enter+0x12/0x20
> [199141.434771]  call_cpuidle+0x1e/0x30
> [199141.434779]  do_idle+0xde/0x180
> [199141.434788]  cpu_startup_entry+0x6c/0x70
> [199141.434796]  start_secondary+0x13c/0x160
> [199141.434808]  secondary_startup_64+0x9f/0x9f
> [199141.434813] Code: 8c 24 a4 03 00 00 eb 8d 4c 89 e7 c6 05 ea 96 81 00 01
> e8 02 f0 fd ff 89 d9 4c 89 e6 48 c7 c7 f0 49 00 82 48 89 c2 e8 bd 08 6e ff
> <0f> ff eb c1 66 2e 0f 1f 84 00 00 00 00 00 48 8b 4e 48 55 44 8b
> [199141.434895] ---[ end trace 0bac15bcef84778a ]---
> [199141.435208] igb :08:00.2 eth1: Reset adapter
> [199144.839995] igb :08:00.2 eth1: igb: eth1 NIC Link is Up 1000 Mbps
> Full Duplex, Flow Control: RX/TX
>
> Justin.
>


Re: [PATCH] f2fs: let background GC being aware of freezing

2017-07-21 Thread Chao Yu
Hi Jaegeuk,

On 2017/7/22 4:54, Jaegeuk Kim wrote:
> Hi Chao,
> 
> On 07/21, Chao Yu wrote:
>> When ->freeze_fs is called from lvm for doing snapshot, it needs to
>> make sure there will be no more changes in filesystem's data, however,
>> previously, background GC wasn't aware of freezing, so in environment
>> with active background GC thread, data of snapshot becomes unstable.
> 
> What about flush/discard threads?

Updated.

Thanks,

> 
> Thanks,
> 
>>
>> This patch fixes this issue by adding sb_{start,end}_intwrite in GC
>> flow.
>>
>> Signed-off-by: Chao Yu 
>> ---
>>  fs/f2fs/gc.c | 8 ++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
>> index 76ad2c3d88db..1c0117f60083 100644
>> --- a/fs/f2fs/gc.c
>> +++ b/fs/f2fs/gc.c
>> @@ -55,6 +55,8 @@ static int gc_thread_func(void *data)
>>  }
>>  #endif
>>  
>> +sb_start_intwrite(sbi->sb);
>> +
>>  /*
>>   * [GC triggering condition]
>>   * 0. GC is not conducted currently.
>> @@ -69,12 +71,12 @@ static int gc_thread_func(void *data)
>>   * So, I'd like to wait some time to collect dirty segments.
>>   */
>>  if (!mutex_trylock(>gc_mutex))
>> -continue;
>> +goto next;
>>  
>>  if (!is_idle(sbi)) {
>>  increase_sleep_time(gc_th, _ms);
>>  mutex_unlock(>gc_mutex);
>> -continue;
>> +goto next;
>>  }
>>  
>>  if (has_enough_invalid_blocks(sbi))
>> @@ -93,6 +95,8 @@ static int gc_thread_func(void *data)
>>  
>>  /* balancing f2fs's metadata periodically */
>>  f2fs_balance_fs_bg(sbi);
>> +next:
>> +sb_end_intwrite(sbi->sb);
>>  
>>  } while (!kthread_should_stop());
>>  return 0;
>> -- 
>> 2.13.1.388.g69e6b9b4f4a9


Re: [PATCH] f2fs: let background GC being aware of freezing

2017-07-21 Thread Chao Yu
Hi Jaegeuk,

On 2017/7/22 4:54, Jaegeuk Kim wrote:
> Hi Chao,
> 
> On 07/21, Chao Yu wrote:
>> When ->freeze_fs is called from lvm for doing snapshot, it needs to
>> make sure there will be no more changes in filesystem's data, however,
>> previously, background GC wasn't aware of freezing, so in environment
>> with active background GC thread, data of snapshot becomes unstable.
> 
> What about flush/discard threads?

Updated.

Thanks,

> 
> Thanks,
> 
>>
>> This patch fixes this issue by adding sb_{start,end}_intwrite in GC
>> flow.
>>
>> Signed-off-by: Chao Yu 
>> ---
>>  fs/f2fs/gc.c | 8 ++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
>> index 76ad2c3d88db..1c0117f60083 100644
>> --- a/fs/f2fs/gc.c
>> +++ b/fs/f2fs/gc.c
>> @@ -55,6 +55,8 @@ static int gc_thread_func(void *data)
>>  }
>>  #endif
>>  
>> +sb_start_intwrite(sbi->sb);
>> +
>>  /*
>>   * [GC triggering condition]
>>   * 0. GC is not conducted currently.
>> @@ -69,12 +71,12 @@ static int gc_thread_func(void *data)
>>   * So, I'd like to wait some time to collect dirty segments.
>>   */
>>  if (!mutex_trylock(>gc_mutex))
>> -continue;
>> +goto next;
>>  
>>  if (!is_idle(sbi)) {
>>  increase_sleep_time(gc_th, _ms);
>>  mutex_unlock(>gc_mutex);
>> -continue;
>> +goto next;
>>  }
>>  
>>  if (has_enough_invalid_blocks(sbi))
>> @@ -93,6 +95,8 @@ static int gc_thread_func(void *data)
>>  
>>  /* balancing f2fs's metadata periodically */
>>  f2fs_balance_fs_bg(sbi);
>> +next:
>> +sb_end_intwrite(sbi->sb);
>>  
>>  } while (!kthread_should_stop());
>>  return 0;
>> -- 
>> 2.13.1.388.g69e6b9b4f4a9


Re: [PATCH v8 1/1] f2fs: dax: implement direct access

2017-07-21 Thread Jaegeuk Kim
Hi Qiuyang,

This fails xfstests/generic/413.

Thanks,

On 07/20, sunqiuyang wrote:
> From: Qiuyang Sun 
> 
> This patch implements Direct Access (DAX) in F2FS, including:
>  - a mount option to choose whether to enable DAX or not
>  - read/write and mmap of regular files in the DAX way
>  - zero-out of unaligned partial blocks in the DAX way
>  - garbage collection of DAX files, by mapping both old and new physical
>addresses of a data page into memory and copy data between them directly
>  - incompatibility of DAX with inline data, atomic or volatile write, 
>collapse|insert_range, etc.
> 
> Signed-off-by: Qiuyang Sun 
> ---
> Changelog v7 -> v8:
>  - Introduce the macro f2fs_dax_file() to judge if a file is DAX for cases
>when CONFIG_FS_DAX is set or not
>  - Return -ENOTSUPP when an operation does not support DAX
>  - In f2fs_iomap_begin(), convert the inline data of an inode (if any) 
>before mapping blocks
>  - Minor cleanups
> ---
>  Documentation/filesystems/f2fs.txt |   2 +
>  fs/f2fs/data.c | 132 +-
>  fs/f2fs/f2fs.h |  15 +++
>  fs/f2fs/file.c | 183 
> -
>  fs/f2fs/gc.c   | 103 -
>  fs/f2fs/inline.c   |   3 +
>  fs/f2fs/inode.c|   8 +-
>  fs/f2fs/namei.c|   5 +
>  fs/f2fs/super.c|  15 +++
>  9 files changed, 454 insertions(+), 12 deletions(-)
> 
> diff --git a/Documentation/filesystems/f2fs.txt 
> b/Documentation/filesystems/f2fs.txt
> index 273ccb2..c86c421 100644
> --- a/Documentation/filesystems/f2fs.txt
> +++ b/Documentation/filesystems/f2fs.txt
> @@ -164,6 +164,8 @@ io_bits=%u Set the bit size of write IO 
> requests. It should be set
> with "mode=lfs".
>  usrquota   Enable plain user disk quota accounting.
>  grpquota   Enable plain group disk quota accounting.
> +daxUse direct access (no page cache). See
> +   Documentation/filesystems/dax.txt.
>  
>  
> 
>  DEBUGFS ENTRIES
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 87c1f41..4eb4b76 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -910,6 +910,15 @@ int f2fs_map_blocks(struct inode *inode, struct 
> f2fs_map_blocks *map,
>   err = -EIO;
>   goto sync_out;
>   }
> + /*
> +  * If newly allocated blocks are to be zeroed out later,
> +  * a single f2fs_map_blocks must not contain both old
> +  * and new blocks at the same time.
> +  */
> + if (flag == F2FS_GET_BLOCK_ZERO
> + && (map->m_flags & F2FS_MAP_MAPPED)
> + && !(map->m_flags & F2FS_MAP_NEW))
> + goto sync_out;
>   if (flag == F2FS_GET_BLOCK_PRE_AIO) {
>   if (blkaddr == NULL_ADDR) {
>   prealloc++;
> @@ -938,6 +947,8 @@ int f2fs_map_blocks(struct inode *inode, struct 
> f2fs_map_blocks *map,
>   blkaddr != NEW_ADDR)
>   goto sync_out;
>   }
> + } else if (flag == F2FS_GET_BLOCK_ZERO && map->m_flags & F2FS_MAP_NEW) {
> + goto sync_out;
>   }
>  
>   if (flag == F2FS_GET_BLOCK_PRE_AIO)
> @@ -996,6 +1007,12 @@ int f2fs_map_blocks(struct inode *inode, struct 
> f2fs_map_blocks *map,
>   goto next_dnode;
>  
>  sync_out:
> + if (flag == F2FS_GET_BLOCK_ZERO && map->m_flags & F2FS_MAP_NEW) {
> + clean_bdev_aliases(inode->i_sb->s_bdev,
> + map->m_pblk, map->m_len);
> + err = sb_issue_zeroout(inode->i_sb, map->m_pblk,
> + map->m_len, GFP_NOFS);
> + }
>   f2fs_put_dnode();
>  unlock_out:
>   if (create) {
> @@ -1808,16 +1825,19 @@ static int f2fs_write_data_pages(struct address_space 
> *mapping,
>   return 0;
>  }
>  
> -static void f2fs_write_failed(struct address_space *mapping, loff_t to)
> +static void f2fs_write_failed(struct address_space *mapping, loff_t to,
> + bool lock)
>  {
>   struct inode *inode = mapping->host;
>   loff_t i_size = i_size_read(inode);
>  
>   if (to > i_size) {
> - down_write(_I(inode)->i_mmap_sem);
> + if (lock)
> + down_write(_I(inode)->i_mmap_sem);
>   truncate_pagecache(inode, i_size);
>   truncate_blocks(inode, i_size, true);
> - 

Re: [PATCH v8 1/1] f2fs: dax: implement direct access

2017-07-21 Thread Jaegeuk Kim
Hi Qiuyang,

This fails xfstests/generic/413.

Thanks,

On 07/20, sunqiuyang wrote:
> From: Qiuyang Sun 
> 
> This patch implements Direct Access (DAX) in F2FS, including:
>  - a mount option to choose whether to enable DAX or not
>  - read/write and mmap of regular files in the DAX way
>  - zero-out of unaligned partial blocks in the DAX way
>  - garbage collection of DAX files, by mapping both old and new physical
>addresses of a data page into memory and copy data between them directly
>  - incompatibility of DAX with inline data, atomic or volatile write, 
>collapse|insert_range, etc.
> 
> Signed-off-by: Qiuyang Sun 
> ---
> Changelog v7 -> v8:
>  - Introduce the macro f2fs_dax_file() to judge if a file is DAX for cases
>when CONFIG_FS_DAX is set or not
>  - Return -ENOTSUPP when an operation does not support DAX
>  - In f2fs_iomap_begin(), convert the inline data of an inode (if any) 
>before mapping blocks
>  - Minor cleanups
> ---
>  Documentation/filesystems/f2fs.txt |   2 +
>  fs/f2fs/data.c | 132 +-
>  fs/f2fs/f2fs.h |  15 +++
>  fs/f2fs/file.c | 183 
> -
>  fs/f2fs/gc.c   | 103 -
>  fs/f2fs/inline.c   |   3 +
>  fs/f2fs/inode.c|   8 +-
>  fs/f2fs/namei.c|   5 +
>  fs/f2fs/super.c|  15 +++
>  9 files changed, 454 insertions(+), 12 deletions(-)
> 
> diff --git a/Documentation/filesystems/f2fs.txt 
> b/Documentation/filesystems/f2fs.txt
> index 273ccb2..c86c421 100644
> --- a/Documentation/filesystems/f2fs.txt
> +++ b/Documentation/filesystems/f2fs.txt
> @@ -164,6 +164,8 @@ io_bits=%u Set the bit size of write IO 
> requests. It should be set
> with "mode=lfs".
>  usrquota   Enable plain user disk quota accounting.
>  grpquota   Enable plain group disk quota accounting.
> +daxUse direct access (no page cache). See
> +   Documentation/filesystems/dax.txt.
>  
>  
> 
>  DEBUGFS ENTRIES
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 87c1f41..4eb4b76 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -910,6 +910,15 @@ int f2fs_map_blocks(struct inode *inode, struct 
> f2fs_map_blocks *map,
>   err = -EIO;
>   goto sync_out;
>   }
> + /*
> +  * If newly allocated blocks are to be zeroed out later,
> +  * a single f2fs_map_blocks must not contain both old
> +  * and new blocks at the same time.
> +  */
> + if (flag == F2FS_GET_BLOCK_ZERO
> + && (map->m_flags & F2FS_MAP_MAPPED)
> + && !(map->m_flags & F2FS_MAP_NEW))
> + goto sync_out;
>   if (flag == F2FS_GET_BLOCK_PRE_AIO) {
>   if (blkaddr == NULL_ADDR) {
>   prealloc++;
> @@ -938,6 +947,8 @@ int f2fs_map_blocks(struct inode *inode, struct 
> f2fs_map_blocks *map,
>   blkaddr != NEW_ADDR)
>   goto sync_out;
>   }
> + } else if (flag == F2FS_GET_BLOCK_ZERO && map->m_flags & F2FS_MAP_NEW) {
> + goto sync_out;
>   }
>  
>   if (flag == F2FS_GET_BLOCK_PRE_AIO)
> @@ -996,6 +1007,12 @@ int f2fs_map_blocks(struct inode *inode, struct 
> f2fs_map_blocks *map,
>   goto next_dnode;
>  
>  sync_out:
> + if (flag == F2FS_GET_BLOCK_ZERO && map->m_flags & F2FS_MAP_NEW) {
> + clean_bdev_aliases(inode->i_sb->s_bdev,
> + map->m_pblk, map->m_len);
> + err = sb_issue_zeroout(inode->i_sb, map->m_pblk,
> + map->m_len, GFP_NOFS);
> + }
>   f2fs_put_dnode();
>  unlock_out:
>   if (create) {
> @@ -1808,16 +1825,19 @@ static int f2fs_write_data_pages(struct address_space 
> *mapping,
>   return 0;
>  }
>  
> -static void f2fs_write_failed(struct address_space *mapping, loff_t to)
> +static void f2fs_write_failed(struct address_space *mapping, loff_t to,
> + bool lock)
>  {
>   struct inode *inode = mapping->host;
>   loff_t i_size = i_size_read(inode);
>  
>   if (to > i_size) {
> - down_write(_I(inode)->i_mmap_sem);
> + if (lock)
> + down_write(_I(inode)->i_mmap_sem);
>   truncate_pagecache(inode, i_size);
>   truncate_blocks(inode, i_size, true);
> - up_write(_I(inode)->i_mmap_sem);
> + if 

Re: [PATCH] perf, tools: Make build fail on JSON parse error

2017-07-21 Thread Sukadev Bhattiprolu
Andi Kleen [a...@firstfloor.org] wrote:
> From: Andi Kleen 
> 
> Today, when a JSON file fails parsing the build continues,
> but there are no json files built in, which is difficult to debug later.
> Make the build stop on a parse error instead.

I see the problem and we were being defensive to not break the build
on architectures that don't yet have the PMU event lists. It will be
good to check build on an architecture other than x86/powerpc.

Also, following comments may no longer be applicable?

diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README
index 1408ade0d773..c2ee3e4417fe 100644
--- a/tools/perf/pmu-events/README
+++ b/tools/perf/pmu-events/README
@@ -85,10 +85,6 @@ users to specify events by their name:
 
 where 'pm_1plus_ppc_cmpl' is a Power8 PMU event.
 
-In case of errors when processing files in the tools/perf/pmu-events/arch
-directory, 'jevents' tries to create an empty mapping file to allow the perf
-build to succeed even if the PMU event aliases cannot be used.
-
 However some errors in processing may cause the perf build to fail.
 
 Mapfile format
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index baa073f38334..f6fb0eebf488 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -826,10 +826,6 @@ static int process_one_file(const char *fpath, const 
struct stat *sb,
  * PMU event tables (see struct pmu_events_map).
  *
  * Write out the PMU events tables and the mapping table to pmu-event.c.
- *
- * If unable to process the JSON or arch files, create an empty mapping
- * table so we can continue to build/use  perf even if we cannot use the
- * PMU event aliases.
  */
 int main(int argc, char *argv[])
 {





> 
> Cc: suka...@linux.vnet.ibm.com
> Signed-off-by: Andi Kleen 
> ---
>  tools/perf/pmu-events/jevents.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
> index 70cbd5bc4819..58b42508c333 100644
> --- a/tools/perf/pmu-events/jevents.c
> +++ b/tools/perf/pmu-events/jevents.c
> @@ -890,6 +890,9 @@ int main(int argc, char *argv[])
>   if (rc && verbose) {
>   pr_info("%s: Error walking file tree %s\n", prog, ldirname);
>   goto empty_map;
> + } else if (rc < 0) {
> + /* Make build fail */
> + return 1;
>   } else if (rc) {
>   goto empty_map;
>   }
> @@ -904,7 +907,8 @@ int main(int argc, char *argv[])
> 
>   if (process_mapfile(eventsfp, mapfile)) {
>   pr_info("%s: Error processing mapfile %s\n", prog, mapfile);
> - goto empty_map;
> + /* Make build fail */
> + return 1;
>   }
> 
>   return 0;
> -- 
> 2.9.4



Re: [PATCH] perf, tools: Make build fail on JSON parse error

2017-07-21 Thread Sukadev Bhattiprolu
Andi Kleen [a...@firstfloor.org] wrote:
> From: Andi Kleen 
> 
> Today, when a JSON file fails parsing the build continues,
> but there are no json files built in, which is difficult to debug later.
> Make the build stop on a parse error instead.

I see the problem and we were being defensive to not break the build
on architectures that don't yet have the PMU event lists. It will be
good to check build on an architecture other than x86/powerpc.

Also, following comments may no longer be applicable?

diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README
index 1408ade0d773..c2ee3e4417fe 100644
--- a/tools/perf/pmu-events/README
+++ b/tools/perf/pmu-events/README
@@ -85,10 +85,6 @@ users to specify events by their name:
 
 where 'pm_1plus_ppc_cmpl' is a Power8 PMU event.
 
-In case of errors when processing files in the tools/perf/pmu-events/arch
-directory, 'jevents' tries to create an empty mapping file to allow the perf
-build to succeed even if the PMU event aliases cannot be used.
-
 However some errors in processing may cause the perf build to fail.
 
 Mapfile format
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index baa073f38334..f6fb0eebf488 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -826,10 +826,6 @@ static int process_one_file(const char *fpath, const 
struct stat *sb,
  * PMU event tables (see struct pmu_events_map).
  *
  * Write out the PMU events tables and the mapping table to pmu-event.c.
- *
- * If unable to process the JSON or arch files, create an empty mapping
- * table so we can continue to build/use  perf even if we cannot use the
- * PMU event aliases.
  */
 int main(int argc, char *argv[])
 {





> 
> Cc: suka...@linux.vnet.ibm.com
> Signed-off-by: Andi Kleen 
> ---
>  tools/perf/pmu-events/jevents.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
> index 70cbd5bc4819..58b42508c333 100644
> --- a/tools/perf/pmu-events/jevents.c
> +++ b/tools/perf/pmu-events/jevents.c
> @@ -890,6 +890,9 @@ int main(int argc, char *argv[])
>   if (rc && verbose) {
>   pr_info("%s: Error walking file tree %s\n", prog, ldirname);
>   goto empty_map;
> + } else if (rc < 0) {
> + /* Make build fail */
> + return 1;
>   } else if (rc) {
>   goto empty_map;
>   }
> @@ -904,7 +907,8 @@ int main(int argc, char *argv[])
> 
>   if (process_mapfile(eventsfp, mapfile)) {
>   pr_info("%s: Error processing mapfile %s\n", prog, mapfile);
> - goto empty_map;
> + /* Make build fail */
> + return 1;
>   }
> 
>   return 0;
> -- 
> 2.9.4



[PATCH v1 02/13] xen/pvcalls: connect to the backend

2017-07-21 Thread Stefano Stabellini
Implement the probe function for the pvcalls frontend. Read the
supported versions, max-page-order and function-calls nodes from
xenstore.

Introduce a data structure named pvcalls_bedata. It contains pointers to
the command ring, the event channel, a list of active sockets and a list
of passive sockets. Lists accesses are protected by a spin_lock.

Introduce a waitqueue to allow waiting for a response on commands sent
to the backend.

Introduce an array of struct xen_pvcalls_response to store commands
responses.

Only one frontend<->backend connection is supported at any given time
for a guest. Store the active frontend device to a static pointer.

Introduce a stub functions for the event handler.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 153 
 1 file changed, 153 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index 173e204..fb08ebf 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -20,6 +20,29 @@
 #include 
 #include 
 
+#define PVCALLS_INVALID_ID (UINT_MAX)
+#define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
+#define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
+
+struct pvcalls_bedata {
+   struct xen_pvcalls_front_ring ring;
+   grant_ref_t ref;
+   int irq;
+
+   struct list_head socket_mappings;
+   struct list_head socketpass_mappings;
+   spinlock_t pvcallss_lock;
+
+   wait_queue_head_t inflight_req;
+   struct xen_pvcalls_response rsp[PVCALLS_NR_REQ_PER_RING];
+};
+struct xenbus_device *pvcalls_front_dev;
+
+static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
+{
+   return IRQ_HANDLED;
+}
+
 static const struct xenbus_device_id pvcalls_front_ids[] = {
{ "pvcalls" },
{ "" }
@@ -33,7 +56,114 @@ static int pvcalls_front_remove(struct xenbus_device *dev)
 static int pvcalls_front_probe(struct xenbus_device *dev,
  const struct xenbus_device_id *id)
 {
+   int ret = -EFAULT, evtchn, ref = -1, i;
+   unsigned int max_page_order, function_calls, len;
+   char *versions;
+   grant_ref_t gref_head = 0;
+   struct xenbus_transaction xbt;
+   struct pvcalls_bedata *bedata = NULL;
+   struct xen_pvcalls_sring *sring;
+
+   if (pvcalls_front_dev != NULL) {
+   dev_err(>dev, "only one PV Calls connection supported\n");
+   return -EINVAL;
+   }
+
+   versions = xenbus_read(XBT_NIL, dev->otherend, "versions", );
+   if (!len)
+   return -EINVAL;
+   if (strcmp(versions, "1")) {
+   kfree(versions);
+   return -EINVAL;
+   }
+   kfree(versions);
+   ret = xenbus_scanf(XBT_NIL, dev->otherend,
+  "max-page-order", "%u", _page_order);
+   if (ret <= 0)
+   return -ENODEV;
+   if (max_page_order < RING_ORDER)
+   return -ENODEV;
+   ret = xenbus_scanf(XBT_NIL, dev->otherend,
+  "function-calls", "%u", _calls);
+   if (ret <= 0 || function_calls != 1)
+   return -ENODEV;
+   pr_info("%s max-page-order is %u\n", __func__, max_page_order);
+
+   bedata = kzalloc(sizeof(struct pvcalls_bedata), GFP_KERNEL);
+   if (!bedata)
+   return -ENOMEM;
+
+   init_waitqueue_head(>inflight_req);
+   for (i = 0; i < PVCALLS_NR_REQ_PER_RING; i++)
+   bedata->rsp[i].req_id = PVCALLS_INVALID_ID;
+
+   sring = (struct xen_pvcalls_sring *) __get_free_page(GFP_KERNEL |
+__GFP_ZERO);
+   if (!sring)
+   goto error;
+   SHARED_RING_INIT(sring);
+   FRONT_RING_INIT(>ring, sring, XEN_PAGE_SIZE);
+
+   ret = xenbus_alloc_evtchn(dev, );
+   if (ret)
+   goto error;
+
+   bedata->irq = bind_evtchn_to_irqhandler(evtchn,
+   pvcalls_front_event_handler,
+   0, "pvcalls-frontend", dev);
+   if (bedata->irq < 0) {
+   ret = bedata->irq;
+   goto error;
+   }
+
+   ret = gnttab_alloc_grant_references(1, _head);
+   if (ret < 0)
+   goto error;
+   bedata->ref = ref = gnttab_claim_grant_reference(_head);
+   if (ref < 0)
+   goto error;
+   gnttab_grant_foreign_access_ref(ref, dev->otherend_id,
+   virt_to_gfn((void *)sring), 0);
+
+ again:
+   ret = xenbus_transaction_start();
+   if (ret) {
+   xenbus_dev_fatal(dev, ret, "starting transaction");
+   goto error;
+   }
+   ret = xenbus_printf(xbt, dev->nodename, "version", "%u", 1);
+   if (ret)
+   goto error_xenbus;
+   ret = xenbus_printf(xbt, 

[PATCH v1 02/13] xen/pvcalls: connect to the backend

2017-07-21 Thread Stefano Stabellini
Implement the probe function for the pvcalls frontend. Read the
supported versions, max-page-order and function-calls nodes from
xenstore.

Introduce a data structure named pvcalls_bedata. It contains pointers to
the command ring, the event channel, a list of active sockets and a list
of passive sockets. Lists accesses are protected by a spin_lock.

Introduce a waitqueue to allow waiting for a response on commands sent
to the backend.

Introduce an array of struct xen_pvcalls_response to store commands
responses.

Only one frontend<->backend connection is supported at any given time
for a guest. Store the active frontend device to a static pointer.

Introduce a stub functions for the event handler.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 153 
 1 file changed, 153 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index 173e204..fb08ebf 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -20,6 +20,29 @@
 #include 
 #include 
 
+#define PVCALLS_INVALID_ID (UINT_MAX)
+#define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
+#define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
+
+struct pvcalls_bedata {
+   struct xen_pvcalls_front_ring ring;
+   grant_ref_t ref;
+   int irq;
+
+   struct list_head socket_mappings;
+   struct list_head socketpass_mappings;
+   spinlock_t pvcallss_lock;
+
+   wait_queue_head_t inflight_req;
+   struct xen_pvcalls_response rsp[PVCALLS_NR_REQ_PER_RING];
+};
+struct xenbus_device *pvcalls_front_dev;
+
+static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
+{
+   return IRQ_HANDLED;
+}
+
 static const struct xenbus_device_id pvcalls_front_ids[] = {
{ "pvcalls" },
{ "" }
@@ -33,7 +56,114 @@ static int pvcalls_front_remove(struct xenbus_device *dev)
 static int pvcalls_front_probe(struct xenbus_device *dev,
  const struct xenbus_device_id *id)
 {
+   int ret = -EFAULT, evtchn, ref = -1, i;
+   unsigned int max_page_order, function_calls, len;
+   char *versions;
+   grant_ref_t gref_head = 0;
+   struct xenbus_transaction xbt;
+   struct pvcalls_bedata *bedata = NULL;
+   struct xen_pvcalls_sring *sring;
+
+   if (pvcalls_front_dev != NULL) {
+   dev_err(>dev, "only one PV Calls connection supported\n");
+   return -EINVAL;
+   }
+
+   versions = xenbus_read(XBT_NIL, dev->otherend, "versions", );
+   if (!len)
+   return -EINVAL;
+   if (strcmp(versions, "1")) {
+   kfree(versions);
+   return -EINVAL;
+   }
+   kfree(versions);
+   ret = xenbus_scanf(XBT_NIL, dev->otherend,
+  "max-page-order", "%u", _page_order);
+   if (ret <= 0)
+   return -ENODEV;
+   if (max_page_order < RING_ORDER)
+   return -ENODEV;
+   ret = xenbus_scanf(XBT_NIL, dev->otherend,
+  "function-calls", "%u", _calls);
+   if (ret <= 0 || function_calls != 1)
+   return -ENODEV;
+   pr_info("%s max-page-order is %u\n", __func__, max_page_order);
+
+   bedata = kzalloc(sizeof(struct pvcalls_bedata), GFP_KERNEL);
+   if (!bedata)
+   return -ENOMEM;
+
+   init_waitqueue_head(>inflight_req);
+   for (i = 0; i < PVCALLS_NR_REQ_PER_RING; i++)
+   bedata->rsp[i].req_id = PVCALLS_INVALID_ID;
+
+   sring = (struct xen_pvcalls_sring *) __get_free_page(GFP_KERNEL |
+__GFP_ZERO);
+   if (!sring)
+   goto error;
+   SHARED_RING_INIT(sring);
+   FRONT_RING_INIT(>ring, sring, XEN_PAGE_SIZE);
+
+   ret = xenbus_alloc_evtchn(dev, );
+   if (ret)
+   goto error;
+
+   bedata->irq = bind_evtchn_to_irqhandler(evtchn,
+   pvcalls_front_event_handler,
+   0, "pvcalls-frontend", dev);
+   if (bedata->irq < 0) {
+   ret = bedata->irq;
+   goto error;
+   }
+
+   ret = gnttab_alloc_grant_references(1, _head);
+   if (ret < 0)
+   goto error;
+   bedata->ref = ref = gnttab_claim_grant_reference(_head);
+   if (ref < 0)
+   goto error;
+   gnttab_grant_foreign_access_ref(ref, dev->otherend_id,
+   virt_to_gfn((void *)sring), 0);
+
+ again:
+   ret = xenbus_transaction_start();
+   if (ret) {
+   xenbus_dev_fatal(dev, ret, "starting transaction");
+   goto error;
+   }
+   ret = xenbus_printf(xbt, dev->nodename, "version", "%u", 1);
+   if (ret)
+   goto error_xenbus;
+   ret = xenbus_printf(xbt, dev->nodename, "ring-ref", 

[PATCH v1 03/13] xen/pvcalls: implement socket command and handle events

2017-07-21 Thread Stefano Stabellini
Send a PVCALLS_SOCKET command to the backend, use the masked
req_prod_pvt as req_id. This way, req_id is guaranteed to be between 0
and PVCALLS_NR_REQ_PER_RING. We already have a slot in the rsp array
ready for the response, and there cannot be two outstanding responses
with the same req_id.

Wait for the response by waiting on the inflight_req waitqueue and
check for the req_id field in rsp[req_id]. Use atomic accesses to
read the field. Once a response is received, clear the corresponding rsp
slot by setting req_id to PVCALLS_INVALID_ID. Note that
PVCALLS_INVALID_ID is invalid only from the frontend point of view. It
is not part of the PVCalls protocol.

pvcalls_front_event_handler is in charge of copying responses from the
ring to the appropriate rsp slot. It is done by copying the body of the
response first, then by copying req_id atomically. After the copies,
wake up anybody waiting on waitqueue.

pvcallss_lock protects accesses to the ring.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 91 +
 drivers/xen/pvcalls-front.h |  8 
 2 files changed, 99 insertions(+)
 create mode 100644 drivers/xen/pvcalls-front.h

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index fb08ebf..7933c73 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -40,9 +40,100 @@ struct pvcalls_bedata {
 
 static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
 {
+   struct xenbus_device *dev = dev_id;
+   struct pvcalls_bedata *bedata;
+   struct xen_pvcalls_response *rsp;
+   uint8_t *src, *dst;
+   int req_id = 0, more = 0;
+
+   if (dev == NULL)
+   return IRQ_HANDLED;
+
+   bedata = dev_get_drvdata(>dev);
+   if (bedata == NULL)
+   return IRQ_HANDLED;
+
+again:
+   while (RING_HAS_UNCONSUMED_RESPONSES(>ring)) {
+   rsp = RING_GET_RESPONSE(>ring, bedata->ring.rsp_cons);
+
+   req_id = rsp->req_id;
+   src = (uint8_t *)>rsp[req_id];
+   src += sizeof(rsp->req_id);
+   dst = (uint8_t *)rsp;
+   dst += sizeof(rsp->req_id);
+   memcpy(dst, src, sizeof(*rsp) - sizeof(rsp->req_id));
+   /*
+* First copy the rest of the data, then req_id. It is
+* paired with the barrier when accessing bedata->rsp.
+*/
+   smp_wmb();
+   WRITE_ONCE(bedata->rsp[req_id].req_id, rsp->req_id);
+
+   bedata->ring.rsp_cons++;
+   wake_up(>inflight_req);
+   }
+
+   RING_FINAL_CHECK_FOR_RESPONSES(>ring, more);
+   if (more)
+   goto again;
return IRQ_HANDLED;
 }
 
+int pvcalls_front_socket(struct socket *sock)
+{
+   struct pvcalls_bedata *bedata;
+   struct xen_pvcalls_request *req;
+   int notify, req_id, ret;
+
+   if (!pvcalls_front_dev)
+   return -EACCES;
+   /*
+* PVCalls only supports domain AF_INET,
+* type SOCK_STREAM and protocol 0 sockets for now.
+*
+* Check socket type here, AF_INET and protocol checks are done
+* by the caller.
+*/
+   if (sock->type != SOCK_STREAM)
+   return -ENOTSUPP;
+
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   spin_lock(>pvcallss_lock);
+   req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
+   BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);
+   if (RING_FULL(>ring) ||
+   READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
+   spin_unlock(>pvcallss_lock);
+   return -EAGAIN;
+   }
+   req = RING_GET_REQUEST(>ring, req_id);
+   req->req_id = req_id;
+   req->cmd = PVCALLS_SOCKET;
+   req->u.socket.id = (uint64_t) sock;
+   req->u.socket.domain = AF_INET;
+   req->u.socket.type = SOCK_STREAM;
+   req->u.socket.protocol = 0;
+
+   bedata->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
+   spin_unlock(>pvcallss_lock);
+   if (notify)
+   notify_remote_via_irq(bedata->irq);
+
+   if (wait_event_interruptible(bedata->inflight_req,
+   READ_ONCE(bedata->rsp[req_id].req_id) == req_id) != 0)
+   return -EINTR;
+
+   ret = bedata->rsp[req_id].ret;
+   /* read ret, then set this rsp slot to be reused */
+   smp_mb();
+   WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
+
+   return ret;
+}
+
 static const struct xenbus_device_id pvcalls_front_ids[] = {
{ "pvcalls" },
{ "" }
diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
new file mode 100644
index 000..b7dabed
--- /dev/null
+++ b/drivers/xen/pvcalls-front.h
@@ -0,0 +1,8 @@
+#ifndef __PVCALLS_FRONT_H__
+#define __PVCALLS_FRONT_H__
+
+#include 
+

[PATCH v1 04/13] xen/pvcalls: implement connect command

2017-07-21 Thread Stefano Stabellini
Send PVCALLS_CONNECT to the backend. Allocate a new ring and evtchn for
the active socket.

Introduce a data structure to keep track of sockets. Introduce a
waitqueue to allow the frontend to wait on data coming from the backend
on the active socket (recvmsg command).

Two mutexes (one of reads and one for writes) will be used to protect
the active socket in and out rings from concurrent accesses.

sock->sk->sk_send_head is not used for ip sockets: reuse the field to
store a pointer to the struct sock_mapping corresponding to the socket.
This way, we can easily get the struct sock_mapping from the struct
socket.

Convert the struct socket pointer into an uint64_t and use it as id for
the new socket to pass to the backend.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 153 
 drivers/xen/pvcalls-front.h |   2 +
 2 files changed, 155 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index 7933c73..0d305e0 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -13,6 +13,8 @@
  */
 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -20,6 +22,8 @@
 #include 
 #include 
 
+#include 
+
 #define PVCALLS_INVALID_ID (UINT_MAX)
 #define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
 #define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
@@ -38,6 +42,24 @@ struct pvcalls_bedata {
 };
 struct xenbus_device *pvcalls_front_dev;
 
+struct sock_mapping {
+   bool active_socket;
+   struct list_head list;
+   struct socket *sock;
+   union {
+   struct {
+   int irq;
+   grant_ref_t ref;
+   struct pvcalls_data_intf *ring;
+   struct pvcalls_data data;
+   struct mutex in_mutex;
+   struct mutex out_mutex;
+
+   wait_queue_head_t inflight_conn_req;
+   } active;
+   };
+};
+
 static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
 {
struct xenbus_device *dev = dev_id;
@@ -80,6 +102,18 @@ static irqreturn_t pvcalls_front_event_handler(int irq, 
void *dev_id)
return IRQ_HANDLED;
 }
 
+static irqreturn_t pvcalls_front_conn_handler(int irq, void *sock_map)
+{
+   struct sock_mapping *map = sock_map;
+
+   if (map == NULL)
+   return IRQ_HANDLED;
+
+   wake_up_interruptible(>active.inflight_conn_req);
+
+   return IRQ_HANDLED;
+}
+
 int pvcalls_front_socket(struct socket *sock)
 {
struct pvcalls_bedata *bedata;
@@ -134,6 +168,125 @@ int pvcalls_front_socket(struct socket *sock)
return ret;
 }
 
+static struct sock_mapping *create_active(int *evtchn)
+{
+   struct sock_mapping *map = NULL;
+   void *bytes;
+   int ret, irq = -1, i;
+
+   map = kzalloc(sizeof(*map), GFP_KERNEL);
+   if (map == NULL)
+   return NULL;
+
+   init_waitqueue_head(>active.inflight_conn_req);
+
+   map->active.ring = (struct pvcalls_data_intf *)
+   __get_free_page(GFP_KERNEL | __GFP_ZERO);
+   if (map->active.ring == NULL)
+   goto out_error;
+   memset(map->active.ring, 0, XEN_PAGE_SIZE);
+   map->active.ring->ring_order = RING_ORDER;
+   bytes = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
+   map->active.ring->ring_order);
+   if (bytes == NULL)
+   goto out_error;
+   for (i = 0; i < (1 << map->active.ring->ring_order); i++)
+   map->active.ring->ref[i] = gnttab_grant_foreign_access(
+   pvcalls_front_dev->otherend_id,
+   pfn_to_gfn(virt_to_pfn(bytes) + i), 0);
+
+   map->active.ref = gnttab_grant_foreign_access(
+   pvcalls_front_dev->otherend_id,
+   pfn_to_gfn(virt_to_pfn((void *)map->active.ring)), 0);
+
+   ret = xenbus_alloc_evtchn(pvcalls_front_dev, evtchn);
+   if (ret)
+   goto out_error;
+   map->active.data.in = bytes;
+   map->active.data.out = bytes +
+   XEN_FLEX_RING_SIZE(map->active.ring->ring_order);
+   irq = bind_evtchn_to_irqhandler(*evtchn, pvcalls_front_conn_handler,
+   0, "pvcalls-frontend", map);
+   if (irq < 0)
+   goto out_error;
+
+   map->active.irq = irq;
+   map->active_socket = true;
+   mutex_init(>active.in_mutex);
+   mutex_init(>active.out_mutex);
+
+   return map;
+
+out_error:
+   if (irq >= 0)
+   unbind_from_irqhandler(irq, map);
+   else if (*evtchn >= 0)
+   xenbus_free_evtchn(pvcalls_front_dev, *evtchn);
+   kfree(map->active.data.in);
+   kfree(map->active.ring);
+   kfree(map);
+   return NULL;
+}
+
+int pvcalls_front_connect(struct socket *sock, 

[PATCH v1 04/13] xen/pvcalls: implement connect command

2017-07-21 Thread Stefano Stabellini
Send PVCALLS_CONNECT to the backend. Allocate a new ring and evtchn for
the active socket.

Introduce a data structure to keep track of sockets. Introduce a
waitqueue to allow the frontend to wait on data coming from the backend
on the active socket (recvmsg command).

Two mutexes (one of reads and one for writes) will be used to protect
the active socket in and out rings from concurrent accesses.

sock->sk->sk_send_head is not used for ip sockets: reuse the field to
store a pointer to the struct sock_mapping corresponding to the socket.
This way, we can easily get the struct sock_mapping from the struct
socket.

Convert the struct socket pointer into an uint64_t and use it as id for
the new socket to pass to the backend.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 153 
 drivers/xen/pvcalls-front.h |   2 +
 2 files changed, 155 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index 7933c73..0d305e0 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -13,6 +13,8 @@
  */
 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -20,6 +22,8 @@
 #include 
 #include 
 
+#include 
+
 #define PVCALLS_INVALID_ID (UINT_MAX)
 #define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
 #define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
@@ -38,6 +42,24 @@ struct pvcalls_bedata {
 };
 struct xenbus_device *pvcalls_front_dev;
 
+struct sock_mapping {
+   bool active_socket;
+   struct list_head list;
+   struct socket *sock;
+   union {
+   struct {
+   int irq;
+   grant_ref_t ref;
+   struct pvcalls_data_intf *ring;
+   struct pvcalls_data data;
+   struct mutex in_mutex;
+   struct mutex out_mutex;
+
+   wait_queue_head_t inflight_conn_req;
+   } active;
+   };
+};
+
 static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
 {
struct xenbus_device *dev = dev_id;
@@ -80,6 +102,18 @@ static irqreturn_t pvcalls_front_event_handler(int irq, 
void *dev_id)
return IRQ_HANDLED;
 }
 
+static irqreturn_t pvcalls_front_conn_handler(int irq, void *sock_map)
+{
+   struct sock_mapping *map = sock_map;
+
+   if (map == NULL)
+   return IRQ_HANDLED;
+
+   wake_up_interruptible(>active.inflight_conn_req);
+
+   return IRQ_HANDLED;
+}
+
 int pvcalls_front_socket(struct socket *sock)
 {
struct pvcalls_bedata *bedata;
@@ -134,6 +168,125 @@ int pvcalls_front_socket(struct socket *sock)
return ret;
 }
 
+static struct sock_mapping *create_active(int *evtchn)
+{
+   struct sock_mapping *map = NULL;
+   void *bytes;
+   int ret, irq = -1, i;
+
+   map = kzalloc(sizeof(*map), GFP_KERNEL);
+   if (map == NULL)
+   return NULL;
+
+   init_waitqueue_head(>active.inflight_conn_req);
+
+   map->active.ring = (struct pvcalls_data_intf *)
+   __get_free_page(GFP_KERNEL | __GFP_ZERO);
+   if (map->active.ring == NULL)
+   goto out_error;
+   memset(map->active.ring, 0, XEN_PAGE_SIZE);
+   map->active.ring->ring_order = RING_ORDER;
+   bytes = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
+   map->active.ring->ring_order);
+   if (bytes == NULL)
+   goto out_error;
+   for (i = 0; i < (1 << map->active.ring->ring_order); i++)
+   map->active.ring->ref[i] = gnttab_grant_foreign_access(
+   pvcalls_front_dev->otherend_id,
+   pfn_to_gfn(virt_to_pfn(bytes) + i), 0);
+
+   map->active.ref = gnttab_grant_foreign_access(
+   pvcalls_front_dev->otherend_id,
+   pfn_to_gfn(virt_to_pfn((void *)map->active.ring)), 0);
+
+   ret = xenbus_alloc_evtchn(pvcalls_front_dev, evtchn);
+   if (ret)
+   goto out_error;
+   map->active.data.in = bytes;
+   map->active.data.out = bytes +
+   XEN_FLEX_RING_SIZE(map->active.ring->ring_order);
+   irq = bind_evtchn_to_irqhandler(*evtchn, pvcalls_front_conn_handler,
+   0, "pvcalls-frontend", map);
+   if (irq < 0)
+   goto out_error;
+
+   map->active.irq = irq;
+   map->active_socket = true;
+   mutex_init(>active.in_mutex);
+   mutex_init(>active.out_mutex);
+
+   return map;
+
+out_error:
+   if (irq >= 0)
+   unbind_from_irqhandler(irq, map);
+   else if (*evtchn >= 0)
+   xenbus_free_evtchn(pvcalls_front_dev, *evtchn);
+   kfree(map->active.data.in);
+   kfree(map->active.ring);
+   kfree(map);
+   return NULL;
+}
+
+int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr,
+  

[PATCH v1 03/13] xen/pvcalls: implement socket command and handle events

2017-07-21 Thread Stefano Stabellini
Send a PVCALLS_SOCKET command to the backend, use the masked
req_prod_pvt as req_id. This way, req_id is guaranteed to be between 0
and PVCALLS_NR_REQ_PER_RING. We already have a slot in the rsp array
ready for the response, and there cannot be two outstanding responses
with the same req_id.

Wait for the response by waiting on the inflight_req waitqueue and
check for the req_id field in rsp[req_id]. Use atomic accesses to
read the field. Once a response is received, clear the corresponding rsp
slot by setting req_id to PVCALLS_INVALID_ID. Note that
PVCALLS_INVALID_ID is invalid only from the frontend point of view. It
is not part of the PVCalls protocol.

pvcalls_front_event_handler is in charge of copying responses from the
ring to the appropriate rsp slot. It is done by copying the body of the
response first, then by copying req_id atomically. After the copies,
wake up anybody waiting on waitqueue.

pvcallss_lock protects accesses to the ring.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 91 +
 drivers/xen/pvcalls-front.h |  8 
 2 files changed, 99 insertions(+)
 create mode 100644 drivers/xen/pvcalls-front.h

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index fb08ebf..7933c73 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -40,9 +40,100 @@ struct pvcalls_bedata {
 
 static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
 {
+   struct xenbus_device *dev = dev_id;
+   struct pvcalls_bedata *bedata;
+   struct xen_pvcalls_response *rsp;
+   uint8_t *src, *dst;
+   int req_id = 0, more = 0;
+
+   if (dev == NULL)
+   return IRQ_HANDLED;
+
+   bedata = dev_get_drvdata(>dev);
+   if (bedata == NULL)
+   return IRQ_HANDLED;
+
+again:
+   while (RING_HAS_UNCONSUMED_RESPONSES(>ring)) {
+   rsp = RING_GET_RESPONSE(>ring, bedata->ring.rsp_cons);
+
+   req_id = rsp->req_id;
+   src = (uint8_t *)>rsp[req_id];
+   src += sizeof(rsp->req_id);
+   dst = (uint8_t *)rsp;
+   dst += sizeof(rsp->req_id);
+   memcpy(dst, src, sizeof(*rsp) - sizeof(rsp->req_id));
+   /*
+* First copy the rest of the data, then req_id. It is
+* paired with the barrier when accessing bedata->rsp.
+*/
+   smp_wmb();
+   WRITE_ONCE(bedata->rsp[req_id].req_id, rsp->req_id);
+
+   bedata->ring.rsp_cons++;
+   wake_up(>inflight_req);
+   }
+
+   RING_FINAL_CHECK_FOR_RESPONSES(>ring, more);
+   if (more)
+   goto again;
return IRQ_HANDLED;
 }
 
+int pvcalls_front_socket(struct socket *sock)
+{
+   struct pvcalls_bedata *bedata;
+   struct xen_pvcalls_request *req;
+   int notify, req_id, ret;
+
+   if (!pvcalls_front_dev)
+   return -EACCES;
+   /*
+* PVCalls only supports domain AF_INET,
+* type SOCK_STREAM and protocol 0 sockets for now.
+*
+* Check socket type here, AF_INET and protocol checks are done
+* by the caller.
+*/
+   if (sock->type != SOCK_STREAM)
+   return -ENOTSUPP;
+
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   spin_lock(>pvcallss_lock);
+   req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
+   BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);
+   if (RING_FULL(>ring) ||
+   READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
+   spin_unlock(>pvcallss_lock);
+   return -EAGAIN;
+   }
+   req = RING_GET_REQUEST(>ring, req_id);
+   req->req_id = req_id;
+   req->cmd = PVCALLS_SOCKET;
+   req->u.socket.id = (uint64_t) sock;
+   req->u.socket.domain = AF_INET;
+   req->u.socket.type = SOCK_STREAM;
+   req->u.socket.protocol = 0;
+
+   bedata->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
+   spin_unlock(>pvcallss_lock);
+   if (notify)
+   notify_remote_via_irq(bedata->irq);
+
+   if (wait_event_interruptible(bedata->inflight_req,
+   READ_ONCE(bedata->rsp[req_id].req_id) == req_id) != 0)
+   return -EINTR;
+
+   ret = bedata->rsp[req_id].ret;
+   /* read ret, then set this rsp slot to be reused */
+   smp_mb();
+   WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
+
+   return ret;
+}
+
 static const struct xenbus_device_id pvcalls_front_ids[] = {
{ "pvcalls" },
{ "" }
diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
new file mode 100644
index 000..b7dabed
--- /dev/null
+++ b/drivers/xen/pvcalls-front.h
@@ -0,0 +1,8 @@
+#ifndef __PVCALLS_FRONT_H__
+#define __PVCALLS_FRONT_H__
+
+#include 
+
+int 

[PATCH v1 01/13] xen/pvcalls: introduce the pvcalls xenbus frontend

2017-07-21 Thread Stefano Stabellini
Introduce a xenbus frontend for the pvcalls protocol, as defined by
https://xenbits.xen.org/docs/unstable/misc/pvcalls.html.

This patch only adds the stubs, the code will be added by the following
patches.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 68 +
 1 file changed, 68 insertions(+)
 create mode 100644 drivers/xen/pvcalls-front.c

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
new file mode 100644
index 000..173e204
--- /dev/null
+++ b/drivers/xen/pvcalls-front.c
@@ -0,0 +1,68 @@
+/*
+ * (c) 2017 Stefano Stabellini 
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const struct xenbus_device_id pvcalls_front_ids[] = {
+   { "pvcalls" },
+   { "" }
+};
+
+static int pvcalls_front_remove(struct xenbus_device *dev)
+{
+   return 0;
+}
+
+static int pvcalls_front_probe(struct xenbus_device *dev,
+ const struct xenbus_device_id *id)
+{
+   return 0;
+}
+
+static int pvcalls_front_resume(struct xenbus_device *dev)
+{
+   dev_warn(>dev, "suspsend/resume unsupported\n");
+   return 0;
+}
+
+static void pvcalls_front_changed(struct xenbus_device *dev,
+   enum xenbus_state backend_state)
+{
+}
+
+static struct xenbus_driver pvcalls_front_driver = {
+   .ids = pvcalls_front_ids,
+   .probe = pvcalls_front_probe,
+   .remove = pvcalls_front_remove,
+   .resume = pvcalls_front_resume,
+   .otherend_changed = pvcalls_front_changed,
+};
+
+static int __init pvcalls_frontend_init(void)
+{
+   if (!xen_domain())
+   return -ENODEV;
+
+   pr_info("Initialising Xen pvcalls frontend driver\n");
+
+   return xenbus_register_frontend(_front_driver);
+}
+
+module_init(pvcalls_frontend_init);
-- 
1.9.1



[PATCH v1 07/13] xen/pvcalls: implement accept command

2017-07-21 Thread Stefano Stabellini
Send PVCALLS_ACCEPT to the backend. Allocate a new active socket. Make
sure that only one accept command is executed at any given time by
setting PVCALLS_FLAG_ACCEPT_INFLIGHT and waiting on the
inflight_accept_req waitqueue.

sock->sk->sk_send_head is not used for ip sockets: reuse the field to
store a pointer to the struct sock_mapping corresponding to the socket.

Convert the new struct socket pointer into an uint64_t and use it as id
for the new socket to pass to the backend.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 79 +
 drivers/xen/pvcalls-front.h |  3 ++
 2 files changed, 82 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index 80fd5fb..f3a04a2 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -410,6 +410,85 @@ int pvcalls_front_listen(struct socket *sock, int backlog)
return ret;
 }
 
+int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int 
flags)
+{
+   struct pvcalls_bedata *bedata;
+   struct sock_mapping *map;
+   struct sock_mapping *map2 = NULL;
+   struct xen_pvcalls_request *req;
+   int notify, req_id, ret, evtchn;
+
+   if (!pvcalls_front_dev)
+   return -ENOTCONN;
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
+   if (!map)
+   return -ENOTSOCK;
+
+   if (map->passive.status != PVCALLS_STATUS_LISTEN)
+   return -EINVAL;
+
+   /*
+* Backend only supports 1 inflight accept request, will return
+* errors for the others
+*/
+   if (test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
+(void *)>passive.flags)) {
+   if (wait_event_interruptible(map->passive.inflight_accept_req,
+   !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
+ (void *)>passive.flags))
+   != 0)
+   return -EINTR;
+   }
+
+
+   newsock->sk = kzalloc(sizeof(*newsock->sk), GFP_KERNEL);
+   if (newsock->sk == NULL)
+   return -ENOMEM;
+
+   spin_lock(>pvcallss_lock);
+   req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
+   BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);
+   if (RING_FULL(>ring) ||
+   READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
+   spin_unlock(>pvcallss_lock);
+   return -EAGAIN;
+   }
+
+   map2 = create_active();
+
+   req = RING_GET_REQUEST(>ring, req_id);
+   req->req_id = req_id;
+   req->cmd = PVCALLS_ACCEPT;
+   req->u.accept.id = (uint64_t) sock;
+   req->u.accept.ref = map2->active.ref;
+   req->u.accept.id_new = (uint64_t) newsock;
+   req->u.accept.evtchn = evtchn;
+
+   list_add_tail(>list, >socket_mappings);
+   WRITE_ONCE(newsock->sk->sk_send_head, (void *)map2);
+   map2->sock = newsock;
+
+   bedata->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
+   spin_unlock(>pvcallss_lock);
+   if (notify)
+   notify_remote_via_irq(bedata->irq);
+
+   wait_event(bedata->inflight_req,
+  READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
+
+   clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)>passive.flags);
+   wake_up(>passive.inflight_accept_req);
+
+   ret = bedata->rsp[req_id].ret;
+   /* read ret, then set this rsp slot to be reused */
+   smp_mb();
+   WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
+   return ret;
+}
+
 static const struct xenbus_device_id pvcalls_front_ids[] = {
{ "pvcalls" },
{ "" }
diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
index aa8fe10..ab4f1da 100644
--- a/drivers/xen/pvcalls-front.h
+++ b/drivers/xen/pvcalls-front.h
@@ -10,5 +10,8 @@ int pvcalls_front_bind(struct socket *sock,
   struct sockaddr *addr,
   int addr_len);
 int pvcalls_front_listen(struct socket *sock, int backlog);
+int pvcalls_front_accept(struct socket *sock,
+struct socket *newsock,
+int flags);
 
 #endif
-- 
1.9.1



[PATCH v1 01/13] xen/pvcalls: introduce the pvcalls xenbus frontend

2017-07-21 Thread Stefano Stabellini
Introduce a xenbus frontend for the pvcalls protocol, as defined by
https://xenbits.xen.org/docs/unstable/misc/pvcalls.html.

This patch only adds the stubs, the code will be added by the following
patches.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 68 +
 1 file changed, 68 insertions(+)
 create mode 100644 drivers/xen/pvcalls-front.c

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
new file mode 100644
index 000..173e204
--- /dev/null
+++ b/drivers/xen/pvcalls-front.c
@@ -0,0 +1,68 @@
+/*
+ * (c) 2017 Stefano Stabellini 
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const struct xenbus_device_id pvcalls_front_ids[] = {
+   { "pvcalls" },
+   { "" }
+};
+
+static int pvcalls_front_remove(struct xenbus_device *dev)
+{
+   return 0;
+}
+
+static int pvcalls_front_probe(struct xenbus_device *dev,
+ const struct xenbus_device_id *id)
+{
+   return 0;
+}
+
+static int pvcalls_front_resume(struct xenbus_device *dev)
+{
+   dev_warn(>dev, "suspsend/resume unsupported\n");
+   return 0;
+}
+
+static void pvcalls_front_changed(struct xenbus_device *dev,
+   enum xenbus_state backend_state)
+{
+}
+
+static struct xenbus_driver pvcalls_front_driver = {
+   .ids = pvcalls_front_ids,
+   .probe = pvcalls_front_probe,
+   .remove = pvcalls_front_remove,
+   .resume = pvcalls_front_resume,
+   .otherend_changed = pvcalls_front_changed,
+};
+
+static int __init pvcalls_frontend_init(void)
+{
+   if (!xen_domain())
+   return -ENODEV;
+
+   pr_info("Initialising Xen pvcalls frontend driver\n");
+
+   return xenbus_register_frontend(_front_driver);
+}
+
+module_init(pvcalls_frontend_init);
-- 
1.9.1



[PATCH v1 07/13] xen/pvcalls: implement accept command

2017-07-21 Thread Stefano Stabellini
Send PVCALLS_ACCEPT to the backend. Allocate a new active socket. Make
sure that only one accept command is executed at any given time by
setting PVCALLS_FLAG_ACCEPT_INFLIGHT and waiting on the
inflight_accept_req waitqueue.

sock->sk->sk_send_head is not used for ip sockets: reuse the field to
store a pointer to the struct sock_mapping corresponding to the socket.

Convert the new struct socket pointer into an uint64_t and use it as id
for the new socket to pass to the backend.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 79 +
 drivers/xen/pvcalls-front.h |  3 ++
 2 files changed, 82 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index 80fd5fb..f3a04a2 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -410,6 +410,85 @@ int pvcalls_front_listen(struct socket *sock, int backlog)
return ret;
 }
 
+int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int 
flags)
+{
+   struct pvcalls_bedata *bedata;
+   struct sock_mapping *map;
+   struct sock_mapping *map2 = NULL;
+   struct xen_pvcalls_request *req;
+   int notify, req_id, ret, evtchn;
+
+   if (!pvcalls_front_dev)
+   return -ENOTCONN;
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
+   if (!map)
+   return -ENOTSOCK;
+
+   if (map->passive.status != PVCALLS_STATUS_LISTEN)
+   return -EINVAL;
+
+   /*
+* Backend only supports 1 inflight accept request, will return
+* errors for the others
+*/
+   if (test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
+(void *)>passive.flags)) {
+   if (wait_event_interruptible(map->passive.inflight_accept_req,
+   !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
+ (void *)>passive.flags))
+   != 0)
+   return -EINTR;
+   }
+
+
+   newsock->sk = kzalloc(sizeof(*newsock->sk), GFP_KERNEL);
+   if (newsock->sk == NULL)
+   return -ENOMEM;
+
+   spin_lock(>pvcallss_lock);
+   req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
+   BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);
+   if (RING_FULL(>ring) ||
+   READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
+   spin_unlock(>pvcallss_lock);
+   return -EAGAIN;
+   }
+
+   map2 = create_active();
+
+   req = RING_GET_REQUEST(>ring, req_id);
+   req->req_id = req_id;
+   req->cmd = PVCALLS_ACCEPT;
+   req->u.accept.id = (uint64_t) sock;
+   req->u.accept.ref = map2->active.ref;
+   req->u.accept.id_new = (uint64_t) newsock;
+   req->u.accept.evtchn = evtchn;
+
+   list_add_tail(>list, >socket_mappings);
+   WRITE_ONCE(newsock->sk->sk_send_head, (void *)map2);
+   map2->sock = newsock;
+
+   bedata->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
+   spin_unlock(>pvcallss_lock);
+   if (notify)
+   notify_remote_via_irq(bedata->irq);
+
+   wait_event(bedata->inflight_req,
+  READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
+
+   clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)>passive.flags);
+   wake_up(>passive.inflight_accept_req);
+
+   ret = bedata->rsp[req_id].ret;
+   /* read ret, then set this rsp slot to be reused */
+   smp_mb();
+   WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
+   return ret;
+}
+
 static const struct xenbus_device_id pvcalls_front_ids[] = {
{ "pvcalls" },
{ "" }
diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
index aa8fe10..ab4f1da 100644
--- a/drivers/xen/pvcalls-front.h
+++ b/drivers/xen/pvcalls-front.h
@@ -10,5 +10,8 @@ int pvcalls_front_bind(struct socket *sock,
   struct sockaddr *addr,
   int addr_len);
 int pvcalls_front_listen(struct socket *sock, int backlog);
+int pvcalls_front_accept(struct socket *sock,
+struct socket *newsock,
+int flags);
 
 #endif
-- 
1.9.1



[PATCH v1 09/13] xen/pvcalls: implement recvmsg

2017-07-21 Thread Stefano Stabellini
Implement recvmsg by copying data from the "in" ring. If not enough data
is available and the recvmsg call is blocking, then wait on the
inflight_conn_req waitqueue. Take the active socket in_mutex so that
only one function can access the ring at any given time.

If not enough data is available on the ring, rather than returning
immediately or sleep-waiting, spin for up to 5000 cycles. This small
optimization turns out to improve performance and latency significantly.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 106 
 drivers/xen/pvcalls-front.h |   4 ++
 2 files changed, 110 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index bf29f40..3d1041a 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -94,6 +94,20 @@ static int pvcalls_front_write_todo(struct sock_mapping *map)
return size - pvcalls_queued(prod, cons, size);
 }
 
+static int pvcalls_front_read_todo(struct sock_mapping *map)
+{
+   struct pvcalls_data_intf *intf = map->active.ring;
+   RING_IDX cons, prod;
+   int32_t error;
+
+   cons = intf->in_cons;
+   prod = intf->in_prod;
+   error = intf->in_error;
+   return (error != 0 ||
+   pvcalls_queued(prod, cons,
+  XEN_FLEX_RING_SIZE(intf->ring_order))) != 0;
+}
+
 static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
 {
struct xenbus_device *dev = dev_id;
@@ -413,6 +427,98 @@ int pvcalls_front_sendmsg(struct socket *sock, struct 
msghdr *msg,
return tot_sent;
 }
 
+static int __read_ring(struct pvcalls_data_intf *intf,
+  struct pvcalls_data *data,
+  struct iov_iter *msg_iter,
+  size_t len, int flags)
+{
+   RING_IDX cons, prod, size, masked_prod, masked_cons;
+   RING_IDX array_size = XEN_FLEX_RING_SIZE(intf->ring_order);
+   int32_t error;
+
+   cons = intf->in_cons;
+   prod = intf->in_prod;
+   error = intf->in_error;
+   /* get pointers before reading from the ring */
+   virt_rmb();
+   if (error < 0)
+   return error;
+
+   size = pvcalls_queued(prod, cons, array_size);
+   masked_prod = pvcalls_mask(prod, array_size);
+   masked_cons = pvcalls_mask(cons, array_size);
+
+   if (size == 0)
+   return 0;
+
+   if (len > size)
+   len = size;
+
+   if (masked_prod > masked_cons) {
+   copy_to_iter(data->in + masked_cons, len, msg_iter);
+   } else {
+   if (len > (array_size - masked_cons)) {
+   copy_to_iter(data->in + masked_cons,
+array_size - masked_cons, msg_iter);
+   copy_to_iter(data->in,
+len - (array_size - masked_cons),
+msg_iter);
+   } else {
+   copy_to_iter(data->in + masked_cons, len, msg_iter);
+   }
+   }
+   /* read data from the ring before increasing the index */
+   virt_mb();
+   if (!(flags & MSG_PEEK))
+   intf->in_cons += len;
+
+   return len;
+}
+
+int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+int flags)
+{
+   struct pvcalls_bedata *bedata;
+   int ret = -EAGAIN;
+   struct sock_mapping *map;
+   int count = 0;
+
+   if (!pvcalls_front_dev)
+   return -ENOTCONN;
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
+   if (!map)
+   return -ENOTSOCK;
+
+   if (flags & (MSG_CMSG_CLOEXEC|MSG_ERRQUEUE|MSG_OOB|MSG_TRUNC))
+   return -EOPNOTSUPP;
+
+   mutex_lock(>active.in_mutex);
+   if (len > XEN_FLEX_RING_SIZE(map->active.ring->ring_order))
+   len = XEN_FLEX_RING_SIZE(map->active.ring->ring_order);
+
+   while (!(flags & MSG_DONTWAIT) && !pvcalls_front_read_todo(map)) {
+   if (count < PVCALLS_FRON_MAX_SPIN)
+   count++;
+   else
+   wait_event_interruptible(map->active.inflight_conn_req,
+pvcalls_front_read_todo(map));
+   }
+   ret = __read_ring(map->active.ring, >active.data,
+ >msg_iter, len, flags);
+
+   if (ret > 0)
+   notify_remote_via_irq(map->active.irq);
+   if (ret == 0)
+   ret = -EAGAIN;
+   if (ret == -ENOTCONN)
+   ret = 0;
+
+   mutex_unlock(>active.in_mutex);
+   return ret;
+}
+
 int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int 
addr_len)
 {
struct pvcalls_bedata *bedata;
diff --git 

[PATCH v1 09/13] xen/pvcalls: implement recvmsg

2017-07-21 Thread Stefano Stabellini
Implement recvmsg by copying data from the "in" ring. If not enough data
is available and the recvmsg call is blocking, then wait on the
inflight_conn_req waitqueue. Take the active socket in_mutex so that
only one function can access the ring at any given time.

If not enough data is available on the ring, rather than returning
immediately or sleep-waiting, spin for up to 5000 cycles. This small
optimization turns out to improve performance and latency significantly.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 106 
 drivers/xen/pvcalls-front.h |   4 ++
 2 files changed, 110 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index bf29f40..3d1041a 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -94,6 +94,20 @@ static int pvcalls_front_write_todo(struct sock_mapping *map)
return size - pvcalls_queued(prod, cons, size);
 }
 
+static int pvcalls_front_read_todo(struct sock_mapping *map)
+{
+   struct pvcalls_data_intf *intf = map->active.ring;
+   RING_IDX cons, prod;
+   int32_t error;
+
+   cons = intf->in_cons;
+   prod = intf->in_prod;
+   error = intf->in_error;
+   return (error != 0 ||
+   pvcalls_queued(prod, cons,
+  XEN_FLEX_RING_SIZE(intf->ring_order))) != 0;
+}
+
 static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
 {
struct xenbus_device *dev = dev_id;
@@ -413,6 +427,98 @@ int pvcalls_front_sendmsg(struct socket *sock, struct 
msghdr *msg,
return tot_sent;
 }
 
+static int __read_ring(struct pvcalls_data_intf *intf,
+  struct pvcalls_data *data,
+  struct iov_iter *msg_iter,
+  size_t len, int flags)
+{
+   RING_IDX cons, prod, size, masked_prod, masked_cons;
+   RING_IDX array_size = XEN_FLEX_RING_SIZE(intf->ring_order);
+   int32_t error;
+
+   cons = intf->in_cons;
+   prod = intf->in_prod;
+   error = intf->in_error;
+   /* get pointers before reading from the ring */
+   virt_rmb();
+   if (error < 0)
+   return error;
+
+   size = pvcalls_queued(prod, cons, array_size);
+   masked_prod = pvcalls_mask(prod, array_size);
+   masked_cons = pvcalls_mask(cons, array_size);
+
+   if (size == 0)
+   return 0;
+
+   if (len > size)
+   len = size;
+
+   if (masked_prod > masked_cons) {
+   copy_to_iter(data->in + masked_cons, len, msg_iter);
+   } else {
+   if (len > (array_size - masked_cons)) {
+   copy_to_iter(data->in + masked_cons,
+array_size - masked_cons, msg_iter);
+   copy_to_iter(data->in,
+len - (array_size - masked_cons),
+msg_iter);
+   } else {
+   copy_to_iter(data->in + masked_cons, len, msg_iter);
+   }
+   }
+   /* read data from the ring before increasing the index */
+   virt_mb();
+   if (!(flags & MSG_PEEK))
+   intf->in_cons += len;
+
+   return len;
+}
+
+int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+int flags)
+{
+   struct pvcalls_bedata *bedata;
+   int ret = -EAGAIN;
+   struct sock_mapping *map;
+   int count = 0;
+
+   if (!pvcalls_front_dev)
+   return -ENOTCONN;
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
+   if (!map)
+   return -ENOTSOCK;
+
+   if (flags & (MSG_CMSG_CLOEXEC|MSG_ERRQUEUE|MSG_OOB|MSG_TRUNC))
+   return -EOPNOTSUPP;
+
+   mutex_lock(>active.in_mutex);
+   if (len > XEN_FLEX_RING_SIZE(map->active.ring->ring_order))
+   len = XEN_FLEX_RING_SIZE(map->active.ring->ring_order);
+
+   while (!(flags & MSG_DONTWAIT) && !pvcalls_front_read_todo(map)) {
+   if (count < PVCALLS_FRON_MAX_SPIN)
+   count++;
+   else
+   wait_event_interruptible(map->active.inflight_conn_req,
+pvcalls_front_read_todo(map));
+   }
+   ret = __read_ring(map->active.ring, >active.data,
+ >msg_iter, len, flags);
+
+   if (ret > 0)
+   notify_remote_via_irq(map->active.irq);
+   if (ret == 0)
+   ret = -EAGAIN;
+   if (ret == -ENOTCONN)
+   ret = 0;
+
+   mutex_unlock(>active.in_mutex);
+   return ret;
+}
+
 int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int 
addr_len)
 {
struct pvcalls_bedata *bedata;
diff --git a/drivers/xen/pvcalls-front.h 

[PATCH v1 13/13] xen: introduce a Kconfig option to enable the pvcalls frontend

2017-07-21 Thread Stefano Stabellini
Also add pvcalls-front to the Makefile.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/Kconfig  | 9 +
 drivers/xen/Makefile | 1 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 4545561..ea5e99f 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -196,6 +196,15 @@ config XEN_PCIDEV_BACKEND
 
  If in doubt, say m.
 
+config XEN_PVCALLS_FRONTEND
+   bool "XEN PV Calls frontend driver"
+   depends on INET && XEN
+   help
+ Experimental frontend for the Xen PV Calls protocol
+ (https://xenbits.xen.org/docs/unstable/misc/pvcalls.html). It
+ sends a small set of POSIX calls to the backend, which
+ implements them.
+
 config XEN_PVCALLS_BACKEND
bool "XEN PV Calls backend driver"
depends on INET && XEN && XEN_BACKEND
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 480b928..afb9e03 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_XEN_EFI) += efi.o
 obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-scsiback.o
 obj-$(CONFIG_XEN_AUTO_XLATE)   += xlate_mmu.o
 obj-$(CONFIG_XEN_PVCALLS_BACKEND)  += pvcalls-back.o
+obj-$(CONFIG_XEN_PVCALLS_FRONTEND) += pvcalls-front.o
 xen-evtchn-y   := evtchn.o
 xen-gntdev-y   := gntdev.o
 xen-gntalloc-y := gntalloc.o
-- 
1.9.1



[PATCH v1 13/13] xen: introduce a Kconfig option to enable the pvcalls frontend

2017-07-21 Thread Stefano Stabellini
Also add pvcalls-front to the Makefile.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/Kconfig  | 9 +
 drivers/xen/Makefile | 1 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 4545561..ea5e99f 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -196,6 +196,15 @@ config XEN_PCIDEV_BACKEND
 
  If in doubt, say m.
 
+config XEN_PVCALLS_FRONTEND
+   bool "XEN PV Calls frontend driver"
+   depends on INET && XEN
+   help
+ Experimental frontend for the Xen PV Calls protocol
+ (https://xenbits.xen.org/docs/unstable/misc/pvcalls.html). It
+ sends a small set of POSIX calls to the backend, which
+ implements them.
+
 config XEN_PVCALLS_BACKEND
bool "XEN PV Calls backend driver"
depends on INET && XEN && XEN_BACKEND
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 480b928..afb9e03 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_XEN_EFI) += efi.o
 obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-scsiback.o
 obj-$(CONFIG_XEN_AUTO_XLATE)   += xlate_mmu.o
 obj-$(CONFIG_XEN_PVCALLS_BACKEND)  += pvcalls-back.o
+obj-$(CONFIG_XEN_PVCALLS_FRONTEND) += pvcalls-front.o
 xen-evtchn-y   := evtchn.o
 xen-gntdev-y   := gntdev.o
 xen-gntalloc-y := gntalloc.o
-- 
1.9.1



[PATCH v1 08/13] xen/pvcalls: implement sendmsg

2017-07-21 Thread Stefano Stabellini
Send data to an active socket by copying data to the "out" ring. Take
the active socket out_mutex so that only one function can access the
ring at any given time.

If not enough room is available on the ring, rather than returning
immediately or sleep-waiting, spin for up to 5000 cycles. This small
optimization turns out to improve performance significantly.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 109 
 drivers/xen/pvcalls-front.h |   3 ++
 2 files changed, 112 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index f3a04a2..bf29f40 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -27,6 +27,7 @@
 #define PVCALLS_INVALID_ID (UINT_MAX)
 #define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
 #define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
+#define PVCALLS_FRON_MAX_SPIN 5000
 
 struct pvcalls_bedata {
struct xen_pvcalls_front_ring ring;
@@ -77,6 +78,22 @@ struct sock_mapping {
};
 };
 
+static int pvcalls_front_write_todo(struct sock_mapping *map)
+{
+   struct pvcalls_data_intf *intf = map->active.ring;
+   RING_IDX cons, prod, size = XEN_FLEX_RING_SIZE(intf->ring_order);
+   int32_t error;
+
+   cons = intf->out_cons;
+   prod = intf->out_prod;
+   error = intf->out_error;
+   if (error == -ENOTCONN)
+   return 0;
+   if (error != 0)
+   return error;
+   return size - pvcalls_queued(prod, cons, size);
+}
+
 static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
 {
struct xenbus_device *dev = dev_id;
@@ -304,6 +321,98 @@ int pvcalls_front_connect(struct socket *sock, struct 
sockaddr *addr,
return ret;
 }
 
+static int __write_ring(struct pvcalls_data_intf *intf,
+   struct pvcalls_data *data,
+   struct iov_iter *msg_iter,
+   size_t len)
+{
+   RING_IDX cons, prod, size, masked_prod, masked_cons;
+   RING_IDX array_size = XEN_FLEX_RING_SIZE(intf->ring_order);
+   int32_t error;
+
+   cons = intf->out_cons;
+   prod = intf->out_prod;
+   error = intf->out_error;
+   /* read indexes before continuing */
+   virt_mb();
+
+   if (error < 0)
+   return error;
+
+   size = pvcalls_queued(prod, cons, array_size);
+   if (size >= array_size)
+   return 0;
+   if (len > array_size - size)
+   len = array_size - size;
+
+   masked_prod = pvcalls_mask(prod, array_size);
+   masked_cons = pvcalls_mask(cons, array_size);
+
+   if (masked_prod < masked_cons) {
+   copy_from_iter(data->out + masked_prod, len, msg_iter);
+   } else {
+   if (len > array_size - masked_prod) {
+   copy_from_iter(data->out + masked_prod,
+  array_size - masked_prod, msg_iter);
+   copy_from_iter(data->out,
+  len - (array_size - masked_prod),
+  msg_iter);
+   } else {
+   copy_from_iter(data->out + masked_prod, len, msg_iter);
+   }
+   }
+   /* write to ring before updating pointer */
+   virt_wmb();
+   intf->out_prod += len;
+
+   return len;
+}
+
+int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg,
+ size_t len)
+{
+   struct pvcalls_bedata *bedata;
+   struct sock_mapping *map;
+   int sent = 0, tot_sent = 0;
+   int count = 0, flags;
+
+   if (!pvcalls_front_dev)
+   return -ENOTCONN;
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
+   if (!map)
+   return -ENOTSOCK;
+
+   flags = msg->msg_flags;
+   if (flags & (MSG_CONFIRM|MSG_DONTROUTE|MSG_EOR|MSG_OOB))
+   return -EOPNOTSUPP;
+
+   mutex_lock(>active.out_mutex);
+   if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) {
+   mutex_unlock(>active.out_mutex);
+   return -EAGAIN;
+   }
+
+again:
+   count++;
+   sent = __write_ring(map->active.ring,
+   >active.data, >msg_iter,
+   len);
+   if (sent > 0) {
+   len -= sent;
+   tot_sent += sent;
+   notify_remote_via_irq(map->active.irq);
+   }
+   if (sent >= 0 && len > 0 && count < PVCALLS_FRON_MAX_SPIN)
+   goto again;
+   if (sent < 0)
+   tot_sent = sent;
+
+   mutex_unlock(>active.out_mutex);
+   return tot_sent;
+}
+
 int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int 
addr_len)
 {
struct pvcalls_bedata *bedata;

[PATCH v1 08/13] xen/pvcalls: implement sendmsg

2017-07-21 Thread Stefano Stabellini
Send data to an active socket by copying data to the "out" ring. Take
the active socket out_mutex so that only one function can access the
ring at any given time.

If not enough room is available on the ring, rather than returning
immediately or sleep-waiting, spin for up to 5000 cycles. This small
optimization turns out to improve performance significantly.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 109 
 drivers/xen/pvcalls-front.h |   3 ++
 2 files changed, 112 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index f3a04a2..bf29f40 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -27,6 +27,7 @@
 #define PVCALLS_INVALID_ID (UINT_MAX)
 #define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
 #define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
+#define PVCALLS_FRON_MAX_SPIN 5000
 
 struct pvcalls_bedata {
struct xen_pvcalls_front_ring ring;
@@ -77,6 +78,22 @@ struct sock_mapping {
};
 };
 
+static int pvcalls_front_write_todo(struct sock_mapping *map)
+{
+   struct pvcalls_data_intf *intf = map->active.ring;
+   RING_IDX cons, prod, size = XEN_FLEX_RING_SIZE(intf->ring_order);
+   int32_t error;
+
+   cons = intf->out_cons;
+   prod = intf->out_prod;
+   error = intf->out_error;
+   if (error == -ENOTCONN)
+   return 0;
+   if (error != 0)
+   return error;
+   return size - pvcalls_queued(prod, cons, size);
+}
+
 static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
 {
struct xenbus_device *dev = dev_id;
@@ -304,6 +321,98 @@ int pvcalls_front_connect(struct socket *sock, struct 
sockaddr *addr,
return ret;
 }
 
+static int __write_ring(struct pvcalls_data_intf *intf,
+   struct pvcalls_data *data,
+   struct iov_iter *msg_iter,
+   size_t len)
+{
+   RING_IDX cons, prod, size, masked_prod, masked_cons;
+   RING_IDX array_size = XEN_FLEX_RING_SIZE(intf->ring_order);
+   int32_t error;
+
+   cons = intf->out_cons;
+   prod = intf->out_prod;
+   error = intf->out_error;
+   /* read indexes before continuing */
+   virt_mb();
+
+   if (error < 0)
+   return error;
+
+   size = pvcalls_queued(prod, cons, array_size);
+   if (size >= array_size)
+   return 0;
+   if (len > array_size - size)
+   len = array_size - size;
+
+   masked_prod = pvcalls_mask(prod, array_size);
+   masked_cons = pvcalls_mask(cons, array_size);
+
+   if (masked_prod < masked_cons) {
+   copy_from_iter(data->out + masked_prod, len, msg_iter);
+   } else {
+   if (len > array_size - masked_prod) {
+   copy_from_iter(data->out + masked_prod,
+  array_size - masked_prod, msg_iter);
+   copy_from_iter(data->out,
+  len - (array_size - masked_prod),
+  msg_iter);
+   } else {
+   copy_from_iter(data->out + masked_prod, len, msg_iter);
+   }
+   }
+   /* write to ring before updating pointer */
+   virt_wmb();
+   intf->out_prod += len;
+
+   return len;
+}
+
+int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg,
+ size_t len)
+{
+   struct pvcalls_bedata *bedata;
+   struct sock_mapping *map;
+   int sent = 0, tot_sent = 0;
+   int count = 0, flags;
+
+   if (!pvcalls_front_dev)
+   return -ENOTCONN;
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
+   if (!map)
+   return -ENOTSOCK;
+
+   flags = msg->msg_flags;
+   if (flags & (MSG_CONFIRM|MSG_DONTROUTE|MSG_EOR|MSG_OOB))
+   return -EOPNOTSUPP;
+
+   mutex_lock(>active.out_mutex);
+   if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) {
+   mutex_unlock(>active.out_mutex);
+   return -EAGAIN;
+   }
+
+again:
+   count++;
+   sent = __write_ring(map->active.ring,
+   >active.data, >msg_iter,
+   len);
+   if (sent > 0) {
+   len -= sent;
+   tot_sent += sent;
+   notify_remote_via_irq(map->active.irq);
+   }
+   if (sent >= 0 && len > 0 && count < PVCALLS_FRON_MAX_SPIN)
+   goto again;
+   if (sent < 0)
+   tot_sent = sent;
+
+   mutex_unlock(>active.out_mutex);
+   return tot_sent;
+}
+
 int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int 
addr_len)
 {
struct pvcalls_bedata *bedata;
diff --git 

[PATCH v1 12/13] xen/pvcalls: implement frontend disconnect

2017-07-21 Thread Stefano Stabellini
Implement pvcalls frontend removal function. Go through the list of
active and passive sockets and free them all, one at a time.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index bd3dfac..fcc15fb 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -898,6 +898,34 @@ int pvcalls_front_release(struct socket *sock)
 
 static int pvcalls_front_remove(struct xenbus_device *dev)
 {
+   struct pvcalls_bedata *bedata;
+   struct sock_mapping *map = NULL, *n;
+
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   list_for_each_entry_safe(map, n, >socket_mappings, list) {
+   mutex_lock(>active.in_mutex);
+   mutex_lock(>active.out_mutex);
+   pvcalls_front_free_map(bedata, map);
+   mutex_unlock(>active.out_mutex);
+   mutex_unlock(>active.in_mutex);
+   kfree(map);
+   }
+   list_for_each_entry_safe(map, n, >socketpass_mappings, list) {
+   spin_lock(>pvcallss_lock);
+   list_del_init(>list);
+   spin_unlock(>pvcallss_lock);
+   kfree(map);
+   }
+   if (bedata->irq > 0)
+   unbind_from_irqhandler(bedata->irq, dev);
+   if (bedata->ref >= 0)
+   gnttab_end_foreign_access(bedata->ref, 0, 0);
+   kfree(bedata->ring.sring);
+   kfree(bedata);
+   dev_set_drvdata(>dev, NULL);
+   xenbus_switch_state(dev, XenbusStateClosed);
+   pvcalls_front_dev = NULL;
return 0;
 }
 
-- 
1.9.1



[PATCH v1 12/13] xen/pvcalls: implement frontend disconnect

2017-07-21 Thread Stefano Stabellini
Implement pvcalls frontend removal function. Go through the list of
active and passive sockets and free them all, one at a time.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index bd3dfac..fcc15fb 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -898,6 +898,34 @@ int pvcalls_front_release(struct socket *sock)
 
 static int pvcalls_front_remove(struct xenbus_device *dev)
 {
+   struct pvcalls_bedata *bedata;
+   struct sock_mapping *map = NULL, *n;
+
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   list_for_each_entry_safe(map, n, >socket_mappings, list) {
+   mutex_lock(>active.in_mutex);
+   mutex_lock(>active.out_mutex);
+   pvcalls_front_free_map(bedata, map);
+   mutex_unlock(>active.out_mutex);
+   mutex_unlock(>active.in_mutex);
+   kfree(map);
+   }
+   list_for_each_entry_safe(map, n, >socketpass_mappings, list) {
+   spin_lock(>pvcallss_lock);
+   list_del_init(>list);
+   spin_unlock(>pvcallss_lock);
+   kfree(map);
+   }
+   if (bedata->irq > 0)
+   unbind_from_irqhandler(bedata->irq, dev);
+   if (bedata->ref >= 0)
+   gnttab_end_foreign_access(bedata->ref, 0, 0);
+   kfree(bedata->ring.sring);
+   kfree(bedata);
+   dev_set_drvdata(>dev, NULL);
+   xenbus_switch_state(dev, XenbusStateClosed);
+   pvcalls_front_dev = NULL;
return 0;
 }
 
-- 
1.9.1



[PATCH v1 05/13] xen/pvcalls: implement bind command

2017-07-21 Thread Stefano Stabellini
Send PVCALLS_BIND to the backend. Introduce a new structure, part of
struct sock_mapping, to store information specific to passive sockets.

Introduce a status field to keep track of the status of the passive
socket.

Introduce a waitqueue for the "accept" command (see the accept command
implementation): it is used to allow only one outstanding accept
command at any given time and to implement polling on the passive
socket. Introduce a flags field to keep track of in-flight accept and
poll commands.

sock->sk->sk_send_head is not used for ip sockets: reuse the field to
store a pointer to the struct sock_mapping corresponding to the socket.

Convert the struct socket pointer into an uint64_t and use it as id for
the socket to pass to the backend.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 74 +
 drivers/xen/pvcalls-front.h |  3 ++
 2 files changed, 77 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index 0d305e0..71619bc 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -57,6 +57,23 @@ struct sock_mapping {
 
wait_queue_head_t inflight_conn_req;
} active;
+   struct {
+   /* Socket status */
+#define PVCALLS_STATUS_UNINITALIZED  0
+#define PVCALLS_STATUS_BIND  1
+#define PVCALLS_STATUS_LISTEN2
+   uint8_t status;
+   /*
+* Internal state-machine flags.
+* Only one accept operation can be inflight for a socket.
+* Only one poll operation can be inflight for a given socket.
+*/
+#define PVCALLS_FLAG_ACCEPT_INFLIGHT 0
+#define PVCALLS_FLAG_POLL_INFLIGHT   1
+#define PVCALLS_FLAG_POLL_RET2
+   uint8_t flags;
+   wait_queue_head_t inflight_accept_req;
+   } passive;
};
 };
 
@@ -287,6 +304,63 @@ int pvcalls_front_connect(struct socket *sock, struct 
sockaddr *addr,
return ret;
 }
 
+int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int 
addr_len)
+{
+   struct pvcalls_bedata *bedata;
+   struct sock_mapping *map = NULL;
+   struct xen_pvcalls_request *req;
+   int notify, req_id, ret;
+
+   if (!pvcalls_front_dev)
+   return -ENOTCONN;
+   if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM)
+   return -ENOTSUPP;
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   map = kzalloc(sizeof(*map), GFP_KERNEL);
+   if (map == NULL)
+   return -ENOMEM;
+
+   spin_lock(>pvcallss_lock);
+   req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
+   BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);
+   if (RING_FULL(>ring) ||
+   READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
+   kfree(map);
+   spin_unlock(>pvcallss_lock);
+   return -EAGAIN;
+   }
+   req = RING_GET_REQUEST(>ring, req_id);
+   req->req_id = req_id;
+   map->sock = sock;
+   req->cmd = PVCALLS_BIND;
+   req->u.bind.id = (uint64_t) sock;
+   memcpy(req->u.bind.addr, addr, sizeof(*addr));
+   req->u.bind.len = addr_len;
+
+   init_waitqueue_head(>passive.inflight_accept_req);
+
+   list_add_tail(>list, >socketpass_mappings);
+   WRITE_ONCE(sock->sk->sk_send_head, (void *)map);
+   map->active_socket = false;
+
+   bedata->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
+   spin_unlock(>pvcallss_lock);
+   if (notify)
+   notify_remote_via_irq(bedata->irq);
+
+   wait_event(bedata->inflight_req,
+  READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
+
+   map->passive.status = PVCALLS_STATUS_BIND;
+   ret = bedata->rsp[req_id].ret;
+   /* read ret, then set this rsp slot to be reused */
+   smp_mb();
+   WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
+   return 0;
+}
+
 static const struct xenbus_device_id pvcalls_front_ids[] = {
{ "pvcalls" },
{ "" }
diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
index 63b0417..8b0a274 100644
--- a/drivers/xen/pvcalls-front.h
+++ b/drivers/xen/pvcalls-front.h
@@ -6,5 +6,8 @@
 int pvcalls_front_socket(struct socket *sock);
 int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr,
  int addr_len, int flags);
+int pvcalls_front_bind(struct socket *sock,
+  struct sockaddr *addr,
+  int addr_len);
 
 #endif
-- 
1.9.1



[PATCH v1 06/13] xen/pvcalls: implement listen command

2017-07-21 Thread Stefano Stabellini
Send PVCALLS_LISTEN to the backend.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 49 +
 drivers/xen/pvcalls-front.h |  1 +
 2 files changed, 50 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index 71619bc..80fd5fb 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -361,6 +361,55 @@ int pvcalls_front_bind(struct socket *sock, struct 
sockaddr *addr, int addr_len)
return 0;
 }
 
+int pvcalls_front_listen(struct socket *sock, int backlog)
+{
+   struct pvcalls_bedata *bedata;
+   struct sock_mapping *map;
+   struct xen_pvcalls_request *req;
+   int notify, req_id, ret;
+
+   if (!pvcalls_front_dev)
+   return -ENOTCONN;
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
+   if (!map)
+   return -ENOTSOCK;
+
+   if (map->passive.status != PVCALLS_STATUS_BIND)
+   return -EOPNOTSUPP;
+
+   spin_lock(>pvcallss_lock);
+   req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
+   BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);
+   if (RING_FULL(>ring) ||
+   bedata->rsp[req_id].req_id != PVCALLS_INVALID_ID) {
+   spin_unlock(>pvcallss_lock);
+   return -EAGAIN;
+   }
+   req = RING_GET_REQUEST(>ring, req_id);
+   req->req_id = req_id;
+   req->cmd = PVCALLS_LISTEN;
+   req->u.listen.id = (uint64_t) sock;
+   req->u.listen.backlog = backlog;
+
+   bedata->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
+   spin_unlock(>pvcallss_lock);
+   if (notify)
+   notify_remote_via_irq(bedata->irq);
+
+   wait_event(bedata->inflight_req,
+  READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
+
+   map->passive.status = PVCALLS_STATUS_LISTEN;
+   ret = bedata->rsp[req_id].ret;
+   /* read ret, then set this rsp slot to be reused */
+   smp_mb();
+   WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
+   return ret;
+}
+
 static const struct xenbus_device_id pvcalls_front_ids[] = {
{ "pvcalls" },
{ "" }
diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
index 8b0a274..aa8fe10 100644
--- a/drivers/xen/pvcalls-front.h
+++ b/drivers/xen/pvcalls-front.h
@@ -9,5 +9,6 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr 
*addr,
 int pvcalls_front_bind(struct socket *sock,
   struct sockaddr *addr,
   int addr_len);
+int pvcalls_front_listen(struct socket *sock, int backlog);
 
 #endif
-- 
1.9.1



[PATCH v1 06/13] xen/pvcalls: implement listen command

2017-07-21 Thread Stefano Stabellini
Send PVCALLS_LISTEN to the backend.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 49 +
 drivers/xen/pvcalls-front.h |  1 +
 2 files changed, 50 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index 71619bc..80fd5fb 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -361,6 +361,55 @@ int pvcalls_front_bind(struct socket *sock, struct 
sockaddr *addr, int addr_len)
return 0;
 }
 
+int pvcalls_front_listen(struct socket *sock, int backlog)
+{
+   struct pvcalls_bedata *bedata;
+   struct sock_mapping *map;
+   struct xen_pvcalls_request *req;
+   int notify, req_id, ret;
+
+   if (!pvcalls_front_dev)
+   return -ENOTCONN;
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
+   if (!map)
+   return -ENOTSOCK;
+
+   if (map->passive.status != PVCALLS_STATUS_BIND)
+   return -EOPNOTSUPP;
+
+   spin_lock(>pvcallss_lock);
+   req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
+   BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);
+   if (RING_FULL(>ring) ||
+   bedata->rsp[req_id].req_id != PVCALLS_INVALID_ID) {
+   spin_unlock(>pvcallss_lock);
+   return -EAGAIN;
+   }
+   req = RING_GET_REQUEST(>ring, req_id);
+   req->req_id = req_id;
+   req->cmd = PVCALLS_LISTEN;
+   req->u.listen.id = (uint64_t) sock;
+   req->u.listen.backlog = backlog;
+
+   bedata->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
+   spin_unlock(>pvcallss_lock);
+   if (notify)
+   notify_remote_via_irq(bedata->irq);
+
+   wait_event(bedata->inflight_req,
+  READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
+
+   map->passive.status = PVCALLS_STATUS_LISTEN;
+   ret = bedata->rsp[req_id].ret;
+   /* read ret, then set this rsp slot to be reused */
+   smp_mb();
+   WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
+   return ret;
+}
+
 static const struct xenbus_device_id pvcalls_front_ids[] = {
{ "pvcalls" },
{ "" }
diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
index 8b0a274..aa8fe10 100644
--- a/drivers/xen/pvcalls-front.h
+++ b/drivers/xen/pvcalls-front.h
@@ -9,5 +9,6 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr 
*addr,
 int pvcalls_front_bind(struct socket *sock,
   struct sockaddr *addr,
   int addr_len);
+int pvcalls_front_listen(struct socket *sock, int backlog);
 
 #endif
-- 
1.9.1



[PATCH v1 05/13] xen/pvcalls: implement bind command

2017-07-21 Thread Stefano Stabellini
Send PVCALLS_BIND to the backend. Introduce a new structure, part of
struct sock_mapping, to store information specific to passive sockets.

Introduce a status field to keep track of the status of the passive
socket.

Introduce a waitqueue for the "accept" command (see the accept command
implementation): it is used to allow only one outstanding accept
command at any given time and to implement polling on the passive
socket. Introduce a flags field to keep track of in-flight accept and
poll commands.

sock->sk->sk_send_head is not used for ip sockets: reuse the field to
store a pointer to the struct sock_mapping corresponding to the socket.

Convert the struct socket pointer into an uint64_t and use it as id for
the socket to pass to the backend.

Signed-off-by: Stefano Stabellini 
CC: boris.ostrov...@oracle.com
CC: jgr...@suse.com
---
 drivers/xen/pvcalls-front.c | 74 +
 drivers/xen/pvcalls-front.h |  3 ++
 2 files changed, 77 insertions(+)

diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
index 0d305e0..71619bc 100644
--- a/drivers/xen/pvcalls-front.c
+++ b/drivers/xen/pvcalls-front.c
@@ -57,6 +57,23 @@ struct sock_mapping {
 
wait_queue_head_t inflight_conn_req;
} active;
+   struct {
+   /* Socket status */
+#define PVCALLS_STATUS_UNINITALIZED  0
+#define PVCALLS_STATUS_BIND  1
+#define PVCALLS_STATUS_LISTEN2
+   uint8_t status;
+   /*
+* Internal state-machine flags.
+* Only one accept operation can be inflight for a socket.
+* Only one poll operation can be inflight for a given socket.
+*/
+#define PVCALLS_FLAG_ACCEPT_INFLIGHT 0
+#define PVCALLS_FLAG_POLL_INFLIGHT   1
+#define PVCALLS_FLAG_POLL_RET2
+   uint8_t flags;
+   wait_queue_head_t inflight_accept_req;
+   } passive;
};
 };
 
@@ -287,6 +304,63 @@ int pvcalls_front_connect(struct socket *sock, struct 
sockaddr *addr,
return ret;
 }
 
+int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int 
addr_len)
+{
+   struct pvcalls_bedata *bedata;
+   struct sock_mapping *map = NULL;
+   struct xen_pvcalls_request *req;
+   int notify, req_id, ret;
+
+   if (!pvcalls_front_dev)
+   return -ENOTCONN;
+   if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM)
+   return -ENOTSUPP;
+   bedata = dev_get_drvdata(_front_dev->dev);
+
+   map = kzalloc(sizeof(*map), GFP_KERNEL);
+   if (map == NULL)
+   return -ENOMEM;
+
+   spin_lock(>pvcallss_lock);
+   req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
+   BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);
+   if (RING_FULL(>ring) ||
+   READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
+   kfree(map);
+   spin_unlock(>pvcallss_lock);
+   return -EAGAIN;
+   }
+   req = RING_GET_REQUEST(>ring, req_id);
+   req->req_id = req_id;
+   map->sock = sock;
+   req->cmd = PVCALLS_BIND;
+   req->u.bind.id = (uint64_t) sock;
+   memcpy(req->u.bind.addr, addr, sizeof(*addr));
+   req->u.bind.len = addr_len;
+
+   init_waitqueue_head(>passive.inflight_accept_req);
+
+   list_add_tail(>list, >socketpass_mappings);
+   WRITE_ONCE(sock->sk->sk_send_head, (void *)map);
+   map->active_socket = false;
+
+   bedata->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
+   spin_unlock(>pvcallss_lock);
+   if (notify)
+   notify_remote_via_irq(bedata->irq);
+
+   wait_event(bedata->inflight_req,
+  READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
+
+   map->passive.status = PVCALLS_STATUS_BIND;
+   ret = bedata->rsp[req_id].ret;
+   /* read ret, then set this rsp slot to be reused */
+   smp_mb();
+   WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
+   return 0;
+}
+
 static const struct xenbus_device_id pvcalls_front_ids[] = {
{ "pvcalls" },
{ "" }
diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
index 63b0417..8b0a274 100644
--- a/drivers/xen/pvcalls-front.h
+++ b/drivers/xen/pvcalls-front.h
@@ -6,5 +6,8 @@
 int pvcalls_front_socket(struct socket *sock);
 int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr,
  int addr_len, int flags);
+int pvcalls_front_bind(struct socket *sock,
+  struct sockaddr *addr,
+  int addr_len);
 
 #endif
-- 
1.9.1



[PATCH v1 00/13] introduce the Xen PV Calls frontend

2017-07-21 Thread Stefano Stabellini
Hi all,

this series introduces the frontend for the newly introduced PV Calls
procotol.

PV Calls is a paravirtualized protocol that allows the implementation of
a set of POSIX functions in a different domain. The PV Calls frontend
sends POSIX function calls to the backend, which implements them and
returns a value to the frontend and acts on the function call.

For more information about PV Calls, please read:

https://xenbits.xen.org/docs/unstable/misc/pvcalls.html

This patch series only implements the frontend driver. It doesn't
attempt to redirect POSIX calls to it. The functions exported in
pvcalls-front.h are meant to be used for that. A separate patch series
will be sent to use them and hook them into the system.


Stefano Stabellini (13):
  xen/pvcalls: introduce the pvcalls xenbus frontend
  xen/pvcalls: connect to the backend
  xen/pvcalls: implement socket command and handle events
  xen/pvcalls: implement connect command
  xen/pvcalls: implement bind command
  xen/pvcalls: implement listen command
  xen/pvcalls: implement accept command
  xen/pvcalls: implement sendmsg
  xen/pvcalls: implement recvmsg
  xen/pvcalls: implement poll command
  xen/pvcalls: implement release command
  xen/pvcalls: implement frontend disconnect
  xen: introduce a Kconfig option to enable the pvcalls frontend

 drivers/xen/Kconfig |9 +
 drivers/xen/Makefile|1 +
 drivers/xen/pvcalls-front.c | 1097 +++
 drivers/xen/pvcalls-front.h |   28 ++
 4 files changed, 1135 insertions(+)
 create mode 100644 drivers/xen/pvcalls-front.c
 create mode 100644 drivers/xen/pvcalls-front.h


[PATCH v1 00/13] introduce the Xen PV Calls frontend

2017-07-21 Thread Stefano Stabellini
Hi all,

this series introduces the frontend for the newly introduced PV Calls
procotol.

PV Calls is a paravirtualized protocol that allows the implementation of
a set of POSIX functions in a different domain. The PV Calls frontend
sends POSIX function calls to the backend, which implements them and
returns a value to the frontend and acts on the function call.

For more information about PV Calls, please read:

https://xenbits.xen.org/docs/unstable/misc/pvcalls.html

This patch series only implements the frontend driver. It doesn't
attempt to redirect POSIX calls to it. The functions exported in
pvcalls-front.h are meant to be used for that. A separate patch series
will be sent to use them and hook them into the system.


Stefano Stabellini (13):
  xen/pvcalls: introduce the pvcalls xenbus frontend
  xen/pvcalls: connect to the backend
  xen/pvcalls: implement socket command and handle events
  xen/pvcalls: implement connect command
  xen/pvcalls: implement bind command
  xen/pvcalls: implement listen command
  xen/pvcalls: implement accept command
  xen/pvcalls: implement sendmsg
  xen/pvcalls: implement recvmsg
  xen/pvcalls: implement poll command
  xen/pvcalls: implement release command
  xen/pvcalls: implement frontend disconnect
  xen: introduce a Kconfig option to enable the pvcalls frontend

 drivers/xen/Kconfig |9 +
 drivers/xen/Makefile|1 +
 drivers/xen/pvcalls-front.c | 1097 +++
 drivers/xen/pvcalls-front.h |   28 ++
 4 files changed, 1135 insertions(+)
 create mode 100644 drivers/xen/pvcalls-front.c
 create mode 100644 drivers/xen/pvcalls-front.h


  1   2   3   4   5   6   7   8   9   10   >