Re: [RFC] capabilities: add capability cgroup controller

2016-06-22 Thread Kees Cook
On Wed, Jun 22, 2016 at 5:01 PM, Serge E. Hallyn  wrote:
> Quoting Kees Cook (keesc...@chromium.org):
>> On Wed, Jun 22, 2016 at 11:17 AM, Serge E. Hallyn  wrote:
>> > Quoting Topi Miettinen (toiwo...@gmail.com):
>> >> On 06/22/16 17:14, Serge E. Hallyn wrote:
>> >> > Quoting Topi Miettinen (toiwo...@gmail.com):
>> >> >> On 06/21/16 15:45, Serge E. Hallyn wrote:
>> >> >>> Quoting Topi Miettinen (toiwo...@gmail.com):
>> >>  On 06/19/16 20:01, se...@hallyn.com wrote:
>> >> > apologies for top posting, this phone doesn't support inline)
>> >> >
>> >> > Where are you preventing less privileged tasks from limiting the 
>> >> > caps of a more privileged task?  It looks like you are relying on 
>> >> > the cgroupfs for that?
>> >> 
>> >>  I didn't think that aspect. Some of that could be dealt with by
>> >>  preventing tasks which don't have CAP_SETPCAP to make other tasks 
>> >>  join
>> >>  or set the bounding set. One problem is that the privileges would 
>> >>  not be
>> >>  checked at cgroup.procs open(2) time but only when writing. In 
>> >>  general,
>> >>  less privileged tasks should not be able to gain new capabilities 
>> >>  even
>> >>  if they were somehow able to join the cgroup and also your case must 
>> >>  be
>> >>  addressed in full.
>> >> 
>> >> >
>> >> > Overall I'm not a fan of this for several reasons.  Can you tell us 
>> >> > precisely what your use case is?
>> >> 
>> >>  There are two.
>> >> 
>> >>  1. Capability use tracking at cgroup level. There is no way to know
>> >>  which capabilities have been used and which could be trimmed. With
>> >>  cgroup approach, we can also keep track of how subprocesses use
>> >>  capabilities. Thus the administrator can quickly get a reasonable
>> >>  estimate of a bounding set just by reading the capability.used file.
>> >> >>>
>> >> >>> So to estimate the privileges needed by an application?  Note this
>> >> >>> could also be done with something like systemtap, but that's not as
>> >> >>> friendly of course.
>> >> >>>
>> >> >>
>> >> >> I've used systemtap to track how a single process uses capabilities, 
>> >> >> but
>> >> >> I can imagine that without the cgroup, using it to track several
>> >> >> subprocesses could be difficult.
>> >> >>
>> >> >>> Keeping the tracking part separate from enforcement might be 
>> >> >>> worthwhile.
>> >> >>> If you wanted to push that part of the patchset, we could keep
>> >> >>> discussing the enforcement aspect separately.
>> >> >>>
>> >> >>
>> >> >> OK, I'll prepare the tracking part first.
>> >> >
>> >> > So this does still have some security concerns, namely leaking 
>> >> > information
>> >> > to a less privileged process about what privs a root owned process used.
>> >> > That's not on the same level as giving away details about memory 
>> >> > mappings,
>> >> > but could be an issue.  Kees (cc'd), do you see that as an issue ?
>> >> >
>> >> > thanks,
>> >> > -serge
>> >> >
>> >>
>> >> Anyone can see the full set of capabilities available to each process
>> >
>> > But not the capabilities used.  That's much more invasive.
>> >
>> >> via /proc/pid/status. But should I for example add a new flag
>> >> CFTYPE_OWNER_ONLY to limit reading capability.used file to only owner
>> >> (root) and use it here?
>> >
>> > Not sure that it's needed, let's see what Kees says.  However if it is,
>> > then using owner would not suffice, since that's tangential to the
>> > privilege level of the task.
>>
>> I don't see a problem exposing the history of used capabilities to
>
> Thanks, Kees.
>
>> less privileged processes. The only thing I could see that being used
>> for would be to improve some kind of race against a buggy process
>> where you know caps get used at a certain time in the code, so
>> spinning on reading /proc/pid/status might give you a better chance of
>
> It would actually be a cgroup file, I think someone else was suggesting
> a /proc/pid/status enhancement to the same effect a few weeks ago.

Oh! Sorry, I misunderstood. What does the interface look like for the
new cgroup file? (I assume my evaluation remains the same, though.)

-Kees

>
>> timing the race. That seems like a pretty far-out exposure, though. I
>> imagine instruction counters would give a way finer grained timing
>> too, so I wouldn't object to this being visible.
>>
>> -Kees
>>
>> --
>> Kees Cook
>> Chrome OS & Brillo Security



-- 
Kees Cook
Chrome OS & Brillo Security


Re: [RFC] capabilities: add capability cgroup controller

2016-06-22 Thread Kees Cook
On Wed, Jun 22, 2016 at 5:01 PM, Serge E. Hallyn  wrote:
> Quoting Kees Cook (keesc...@chromium.org):
>> On Wed, Jun 22, 2016 at 11:17 AM, Serge E. Hallyn  wrote:
>> > Quoting Topi Miettinen (toiwo...@gmail.com):
>> >> On 06/22/16 17:14, Serge E. Hallyn wrote:
>> >> > Quoting Topi Miettinen (toiwo...@gmail.com):
>> >> >> On 06/21/16 15:45, Serge E. Hallyn wrote:
>> >> >>> Quoting Topi Miettinen (toiwo...@gmail.com):
>> >>  On 06/19/16 20:01, se...@hallyn.com wrote:
>> >> > apologies for top posting, this phone doesn't support inline)
>> >> >
>> >> > Where are you preventing less privileged tasks from limiting the 
>> >> > caps of a more privileged task?  It looks like you are relying on 
>> >> > the cgroupfs for that?
>> >> 
>> >>  I didn't think that aspect. Some of that could be dealt with by
>> >>  preventing tasks which don't have CAP_SETPCAP to make other tasks 
>> >>  join
>> >>  or set the bounding set. One problem is that the privileges would 
>> >>  not be
>> >>  checked at cgroup.procs open(2) time but only when writing. In 
>> >>  general,
>> >>  less privileged tasks should not be able to gain new capabilities 
>> >>  even
>> >>  if they were somehow able to join the cgroup and also your case must 
>> >>  be
>> >>  addressed in full.
>> >> 
>> >> >
>> >> > Overall I'm not a fan of this for several reasons.  Can you tell us 
>> >> > precisely what your use case is?
>> >> 
>> >>  There are two.
>> >> 
>> >>  1. Capability use tracking at cgroup level. There is no way to know
>> >>  which capabilities have been used and which could be trimmed. With
>> >>  cgroup approach, we can also keep track of how subprocesses use
>> >>  capabilities. Thus the administrator can quickly get a reasonable
>> >>  estimate of a bounding set just by reading the capability.used file.
>> >> >>>
>> >> >>> So to estimate the privileges needed by an application?  Note this
>> >> >>> could also be done with something like systemtap, but that's not as
>> >> >>> friendly of course.
>> >> >>>
>> >> >>
>> >> >> I've used systemtap to track how a single process uses capabilities, 
>> >> >> but
>> >> >> I can imagine that without the cgroup, using it to track several
>> >> >> subprocesses could be difficult.
>> >> >>
>> >> >>> Keeping the tracking part separate from enforcement might be 
>> >> >>> worthwhile.
>> >> >>> If you wanted to push that part of the patchset, we could keep
>> >> >>> discussing the enforcement aspect separately.
>> >> >>>
>> >> >>
>> >> >> OK, I'll prepare the tracking part first.
>> >> >
>> >> > So this does still have some security concerns, namely leaking 
>> >> > information
>> >> > to a less privileged process about what privs a root owned process used.
>> >> > That's not on the same level as giving away details about memory 
>> >> > mappings,
>> >> > but could be an issue.  Kees (cc'd), do you see that as an issue ?
>> >> >
>> >> > thanks,
>> >> > -serge
>> >> >
>> >>
>> >> Anyone can see the full set of capabilities available to each process
>> >
>> > But not the capabilities used.  That's much more invasive.
>> >
>> >> via /proc/pid/status. But should I for example add a new flag
>> >> CFTYPE_OWNER_ONLY to limit reading capability.used file to only owner
>> >> (root) and use it here?
>> >
>> > Not sure that it's needed, let's see what Kees says.  However if it is,
>> > then using owner would not suffice, since that's tangential to the
>> > privilege level of the task.
>>
>> I don't see a problem exposing the history of used capabilities to
>
> Thanks, Kees.
>
>> less privileged processes. The only thing I could see that being used
>> for would be to improve some kind of race against a buggy process
>> where you know caps get used at a certain time in the code, so
>> spinning on reading /proc/pid/status might give you a better chance of
>
> It would actually be a cgroup file, I think someone else was suggesting
> a /proc/pid/status enhancement to the same effect a few weeks ago.

Oh! Sorry, I misunderstood. What does the interface look like for the
new cgroup file? (I assume my evaluation remains the same, though.)

-Kees

>
>> timing the race. That seems like a pretty far-out exposure, though. I
>> imagine instruction counters would give a way finer grained timing
>> too, so I wouldn't object to this being visible.
>>
>> -Kees
>>
>> --
>> Kees Cook
>> Chrome OS & Brillo Security



-- 
Kees Cook
Chrome OS & Brillo Security


Re: [PATCH 21/27] [AARCH64] ILP32: introduce syscalls that pass off_t

2016-06-22 Thread Yury Norov
On Tue, Jun 21, 2016 at 10:35:27AM +, Joseph Myers wrote:
> On Tue, 21 Jun 2016, Yury Norov wrote:
> 
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fallocate.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fallocate64.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/ftruncate.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/ftruncate64.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/llseek.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/lseek.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/mmap.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/posix_fadvise.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/posix_fadvise64.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/pread.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/pread64.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/pwrite.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/pwrite64.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/readahead.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/truncate.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/truncate64.c
> 
> I don't like how you need so many ilp32 files.
> 
> Presumably this is a new convention to be followed for all future ilp32 
> ABIs on 64-bit architectures.  Meaning that you should have some sysdeps 
> macros to say whether this convention is in use and then make either the 
> sysdeps/unix/sysv/linux files, or the .../generic files, or a new 
> architecture-independent sysdeps directory, implement that convention.
> 
> Note also how Adhemerval recently unified pread / pwrite implementations.  
> Adding new files for those functions goes against that unification.
> 
> -- 
> Joseph S. Myers
> jos...@codesourcery.com

Hi Joseph,

There's RISC-V convention that implements very similar approach to
aarch64/ilp32.
https://github.com/manuelafm/riscv-gnu-toolchain/commits/master

But as I understand, there is much work there to be done before upstreaming.

So for now I think it's simpler to have this ABI in sysdeps, and be in
touch with RISC-V team to have aarch64/ilp32 compatible to RISC-V.
After RISC-V merge, we can switch aarch64/ilp32 to it and drop
unneeded sysdeps.

If you mean something different, could you explain it in details, or
suggest an action plan for such rework.

Yury.


Re: [PATCH 21/27] [AARCH64] ILP32: introduce syscalls that pass off_t

2016-06-22 Thread Yury Norov
On Tue, Jun 21, 2016 at 10:35:27AM +, Joseph Myers wrote:
> On Tue, 21 Jun 2016, Yury Norov wrote:
> 
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fallocate.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fallocate64.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/ftruncate.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/ftruncate64.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/llseek.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/lseek.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/mmap.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/posix_fadvise.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/posix_fadvise64.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/pread.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/pread64.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/pwrite.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/pwrite64.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/readahead.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/truncate.c
> >  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/truncate64.c
> 
> I don't like how you need so many ilp32 files.
> 
> Presumably this is a new convention to be followed for all future ilp32 
> ABIs on 64-bit architectures.  Meaning that you should have some sysdeps 
> macros to say whether this convention is in use and then make either the 
> sysdeps/unix/sysv/linux files, or the .../generic files, or a new 
> architecture-independent sysdeps directory, implement that convention.
> 
> Note also how Adhemerval recently unified pread / pwrite implementations.  
> Adding new files for those functions goes against that unification.
> 
> -- 
> Joseph S. Myers
> jos...@codesourcery.com

Hi Joseph,

There's RISC-V convention that implements very similar approach to
aarch64/ilp32.
https://github.com/manuelafm/riscv-gnu-toolchain/commits/master

But as I understand, there is much work there to be done before upstreaming.

So for now I think it's simpler to have this ABI in sysdeps, and be in
touch with RISC-V team to have aarch64/ilp32 compatible to RISC-V.
After RISC-V merge, we can switch aarch64/ilp32 to it and drop
unneeded sysdeps.

If you mean something different, could you explain it in details, or
suggest an action plan for such rework.

Yury.


[PATCH 1/2] net: thunderx: Fix link status reporting

2016-06-22 Thread sunil . kovvuri
From: Sunil Goutham 

Check for SMU RX local/remote faults along with SPU LINK
status. Otherwise at times link is UP at our end but DOWN
at link partner's side. Also due to an issue in BGX it's
rarely seen that initialization doesn't happen properly
and SMU RX reports faults with everything fine at SPU.
This patch tries to reinitialize LMAC to fix it.

Also fixed LMAC disable sequence to properly bring down link.

Signed-off-by: Sunil Goutham 
Signed-off-by: Tao Wang 

---
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 86 +++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h |  2 +
 2 files changed, 57 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c 
b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 3ed2198..b96aae0 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -551,7 +551,9 @@ static int bgx_xaui_check_link(struct lmac *lmac)
}
 
/* Clear rcvflt bit (latching high) and read it back */
-   bgx_reg_modify(bgx, lmacid, BGX_SPUX_STATUS2, SPU_STATUS2_RCVFLT);
+   if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT)
+   bgx_reg_modify(bgx, lmacid,
+  BGX_SPUX_STATUS2, SPU_STATUS2_RCVFLT);
if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT) {
dev_err(>pdev->dev, "Receive fault, retry training\n");
if (bgx->use_training) {
@@ -570,13 +572,6 @@ static int bgx_xaui_check_link(struct lmac *lmac)
return -1;
}
 
-   /* Wait for MAC RX to be ready */
-   if (bgx_poll_reg(bgx, lmacid, BGX_SMUX_RX_CTL,
-SMU_RX_CTL_STATUS, true)) {
-   dev_err(>pdev->dev, "SMU RX link not okay\n");
-   return -1;
-   }
-
/* Wait for BGX RX to be idle */
if (bgx_poll_reg(bgx, lmacid, BGX_SMUX_CTL, SMU_CTL_RX_IDLE, false)) {
dev_err(>pdev->dev, "SMU RX not idle\n");
@@ -589,29 +584,30 @@ static int bgx_xaui_check_link(struct lmac *lmac)
return -1;
}
 
-   if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT) {
-   dev_err(>pdev->dev, "Receive fault\n");
-   return -1;
-   }
-
-   /* Receive link is latching low. Force it high and verify it */
-   bgx_reg_modify(bgx, lmacid, BGX_SPUX_STATUS1, SPU_STATUS1_RCV_LNK);
-   if (bgx_poll_reg(bgx, lmacid, BGX_SPUX_STATUS1,
-SPU_STATUS1_RCV_LNK, false)) {
-   dev_err(>pdev->dev, "SPU receive link down\n");
-   return -1;
-   }
-
+   /* Clear receive packet disable */
cfg = bgx_reg_read(bgx, lmacid, BGX_SPUX_MISC_CONTROL);
cfg &= ~SPU_MISC_CTL_RX_DIS;
bgx_reg_write(bgx, lmacid, BGX_SPUX_MISC_CONTROL, cfg);
-   return 0;
+
+   /* Check for MAC RX faults */
+   cfg = bgx_reg_read(bgx, lmacid, BGX_SMUX_RX_CTL);
+   /* 0 - Link is okay, 1 - Local fault, 2 - Remote fault */
+   cfg &= SMU_RX_CTL_STATUS;
+   if (!cfg)
+   return 0;
+
+   /* Rx local/remote fault seen.
+* Do lmac reinit to see if condition recovers
+*/
+   bgx_lmac_xaui_init(bgx, lmacid, bgx->lmac_type);
+
+   return -1;
 }
 
 static void bgx_poll_for_link(struct work_struct *work)
 {
struct lmac *lmac;
-   u64 link;
+   u64 spu_link, smu_link;
 
lmac = container_of(work, struct lmac, dwork.work);
 
@@ -621,8 +617,11 @@ static void bgx_poll_for_link(struct work_struct *work)
bgx_poll_reg(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1,
 SPU_STATUS1_RCV_LNK, false);
 
-   link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1);
-   if (link & SPU_STATUS1_RCV_LNK) {
+   spu_link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1);
+   smu_link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SMUX_RX_CTL);
+
+   if ((spu_link & SPU_STATUS1_RCV_LNK) &&
+   !(smu_link & SMU_RX_CTL_STATUS)) {
lmac->link_up = 1;
if (lmac->bgx->lmac_type == BGX_MODE_XLAUI)
lmac->last_speed = 4;
@@ -636,9 +635,15 @@ static void bgx_poll_for_link(struct work_struct *work)
}
 
if (lmac->last_link != lmac->link_up) {
+   if (lmac->link_up) {
+   if (bgx_xaui_check_link(lmac)) {
+   /* Errors, clear link_up state */
+   lmac->link_up = 0;
+   lmac->last_speed = SPEED_UNKNOWN;
+   lmac->last_duplex = DUPLEX_UNKNOWN;
+   }
+   }
lmac->last_link = lmac->link_up;
-   if (lmac->link_up)
-   

[PATCH 1/2] net: thunderx: Fix link status reporting

2016-06-22 Thread sunil . kovvuri
From: Sunil Goutham 

Check for SMU RX local/remote faults along with SPU LINK
status. Otherwise at times link is UP at our end but DOWN
at link partner's side. Also due to an issue in BGX it's
rarely seen that initialization doesn't happen properly
and SMU RX reports faults with everything fine at SPU.
This patch tries to reinitialize LMAC to fix it.

Also fixed LMAC disable sequence to properly bring down link.

Signed-off-by: Sunil Goutham 
Signed-off-by: Tao Wang 

---
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 86 +++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h |  2 +
 2 files changed, 57 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c 
b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 3ed2198..b96aae0 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -551,7 +551,9 @@ static int bgx_xaui_check_link(struct lmac *lmac)
}
 
/* Clear rcvflt bit (latching high) and read it back */
-   bgx_reg_modify(bgx, lmacid, BGX_SPUX_STATUS2, SPU_STATUS2_RCVFLT);
+   if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT)
+   bgx_reg_modify(bgx, lmacid,
+  BGX_SPUX_STATUS2, SPU_STATUS2_RCVFLT);
if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT) {
dev_err(>pdev->dev, "Receive fault, retry training\n");
if (bgx->use_training) {
@@ -570,13 +572,6 @@ static int bgx_xaui_check_link(struct lmac *lmac)
return -1;
}
 
-   /* Wait for MAC RX to be ready */
-   if (bgx_poll_reg(bgx, lmacid, BGX_SMUX_RX_CTL,
-SMU_RX_CTL_STATUS, true)) {
-   dev_err(>pdev->dev, "SMU RX link not okay\n");
-   return -1;
-   }
-
/* Wait for BGX RX to be idle */
if (bgx_poll_reg(bgx, lmacid, BGX_SMUX_CTL, SMU_CTL_RX_IDLE, false)) {
dev_err(>pdev->dev, "SMU RX not idle\n");
@@ -589,29 +584,30 @@ static int bgx_xaui_check_link(struct lmac *lmac)
return -1;
}
 
-   if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT) {
-   dev_err(>pdev->dev, "Receive fault\n");
-   return -1;
-   }
-
-   /* Receive link is latching low. Force it high and verify it */
-   bgx_reg_modify(bgx, lmacid, BGX_SPUX_STATUS1, SPU_STATUS1_RCV_LNK);
-   if (bgx_poll_reg(bgx, lmacid, BGX_SPUX_STATUS1,
-SPU_STATUS1_RCV_LNK, false)) {
-   dev_err(>pdev->dev, "SPU receive link down\n");
-   return -1;
-   }
-
+   /* Clear receive packet disable */
cfg = bgx_reg_read(bgx, lmacid, BGX_SPUX_MISC_CONTROL);
cfg &= ~SPU_MISC_CTL_RX_DIS;
bgx_reg_write(bgx, lmacid, BGX_SPUX_MISC_CONTROL, cfg);
-   return 0;
+
+   /* Check for MAC RX faults */
+   cfg = bgx_reg_read(bgx, lmacid, BGX_SMUX_RX_CTL);
+   /* 0 - Link is okay, 1 - Local fault, 2 - Remote fault */
+   cfg &= SMU_RX_CTL_STATUS;
+   if (!cfg)
+   return 0;
+
+   /* Rx local/remote fault seen.
+* Do lmac reinit to see if condition recovers
+*/
+   bgx_lmac_xaui_init(bgx, lmacid, bgx->lmac_type);
+
+   return -1;
 }
 
 static void bgx_poll_for_link(struct work_struct *work)
 {
struct lmac *lmac;
-   u64 link;
+   u64 spu_link, smu_link;
 
lmac = container_of(work, struct lmac, dwork.work);
 
@@ -621,8 +617,11 @@ static void bgx_poll_for_link(struct work_struct *work)
bgx_poll_reg(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1,
 SPU_STATUS1_RCV_LNK, false);
 
-   link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1);
-   if (link & SPU_STATUS1_RCV_LNK) {
+   spu_link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1);
+   smu_link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SMUX_RX_CTL);
+
+   if ((spu_link & SPU_STATUS1_RCV_LNK) &&
+   !(smu_link & SMU_RX_CTL_STATUS)) {
lmac->link_up = 1;
if (lmac->bgx->lmac_type == BGX_MODE_XLAUI)
lmac->last_speed = 4;
@@ -636,9 +635,15 @@ static void bgx_poll_for_link(struct work_struct *work)
}
 
if (lmac->last_link != lmac->link_up) {
+   if (lmac->link_up) {
+   if (bgx_xaui_check_link(lmac)) {
+   /* Errors, clear link_up state */
+   lmac->link_up = 0;
+   lmac->last_speed = SPEED_UNKNOWN;
+   lmac->last_duplex = DUPLEX_UNKNOWN;
+   }
+   }
lmac->last_link = lmac->link_up;
-   if (lmac->link_up)
-   bgx_xaui_check_link(lmac);
}
 

[PATCH 2/2] net: thunderx: Fix TL4 configuration for secondary Qsets

2016-06-22 Thread sunil . kovvuri
From: Sunil Goutham 

TL4 calculation for a given SQ of secondary Qsets is incorrect
and goes out of bounds and also for some SQ's TL4 chosen will
transmit data via a different BGX interface and not same as
primary Qset's interface.

This patch fixes this issue.

Signed-off-by: Sunil Goutham 
---
 drivers/net/ethernet/cavium/thunder/nic_main.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c 
b/drivers/net/ethernet/cavium/thunder/nic_main.c
index 95f17f8..16ed203 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -499,6 +499,7 @@ static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic,
u32 rr_quantum;
u8 sq_idx = sq->sq_num;
u8 pqs_vnic;
+   int svf;
 
if (sq->sqs_mode)
pqs_vnic = nic->pqs_vf[vnic];
@@ -511,10 +512,19 @@ static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic,
/* 24 bytes for FCS, IPG and preamble */
rr_quantum = ((NIC_HW_MAX_FRS + 24) / 4);
 
-   tl4 = (lmac * NIC_TL4_PER_LMAC) + (bgx * NIC_TL4_PER_BGX);
+   if (!sq->sqs_mode) {
+   tl4 = (lmac * NIC_TL4_PER_LMAC) + (bgx * NIC_TL4_PER_BGX);
+   } else {
+   for (svf = 0; svf < MAX_SQS_PER_VF; svf++) {
+   if (nic->vf_sqs[pqs_vnic][svf] == vnic)
+   break;
+   }
+   tl4 = (MAX_LMAC_PER_BGX * NIC_TL4_PER_LMAC);
+   tl4 += (lmac * NIC_TL4_PER_LMAC * MAX_SQS_PER_VF);
+   tl4 += (svf * NIC_TL4_PER_LMAC);
+   tl4 += (bgx * NIC_TL4_PER_BGX);
+   }
tl4 += sq_idx;
-   if (sq->sqs_mode)
-   tl4 += vnic * 8;
 
tl3 = tl4 / (NIC_MAX_TL4 / NIC_MAX_TL3);
nic_reg_write(nic, NIC_PF_QSET_0_127_SQ_0_7_CFG2 |
-- 
2.7.4



[PATCH 2/2] net: thunderx: Fix TL4 configuration for secondary Qsets

2016-06-22 Thread sunil . kovvuri
From: Sunil Goutham 

TL4 calculation for a given SQ of secondary Qsets is incorrect
and goes out of bounds and also for some SQ's TL4 chosen will
transmit data via a different BGX interface and not same as
primary Qset's interface.

This patch fixes this issue.

Signed-off-by: Sunil Goutham 
---
 drivers/net/ethernet/cavium/thunder/nic_main.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c 
b/drivers/net/ethernet/cavium/thunder/nic_main.c
index 95f17f8..16ed203 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -499,6 +499,7 @@ static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic,
u32 rr_quantum;
u8 sq_idx = sq->sq_num;
u8 pqs_vnic;
+   int svf;
 
if (sq->sqs_mode)
pqs_vnic = nic->pqs_vf[vnic];
@@ -511,10 +512,19 @@ static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic,
/* 24 bytes for FCS, IPG and preamble */
rr_quantum = ((NIC_HW_MAX_FRS + 24) / 4);
 
-   tl4 = (lmac * NIC_TL4_PER_LMAC) + (bgx * NIC_TL4_PER_BGX);
+   if (!sq->sqs_mode) {
+   tl4 = (lmac * NIC_TL4_PER_LMAC) + (bgx * NIC_TL4_PER_BGX);
+   } else {
+   for (svf = 0; svf < MAX_SQS_PER_VF; svf++) {
+   if (nic->vf_sqs[pqs_vnic][svf] == vnic)
+   break;
+   }
+   tl4 = (MAX_LMAC_PER_BGX * NIC_TL4_PER_LMAC);
+   tl4 += (lmac * NIC_TL4_PER_LMAC * MAX_SQS_PER_VF);
+   tl4 += (svf * NIC_TL4_PER_LMAC);
+   tl4 += (bgx * NIC_TL4_PER_BGX);
+   }
tl4 += sq_idx;
-   if (sq->sqs_mode)
-   tl4 += vnic * 8;
 
tl3 = tl4 / (NIC_MAX_TL4 / NIC_MAX_TL3);
nic_reg_write(nic, NIC_PF_QSET_0_127_SQ_0_7_CFG2 |
-- 
2.7.4



[PATCH 0/2] net: thunderx: Miscellaneous fixes

2016-06-22 Thread sunil . kovvuri
From: Sunil Goutham 

This 2 patch series fixes issues w.r.t physical link status 
reporting and transmit datapath configuration for 
secondary qsets.

Sunil Goutham (2):
  net: thunderx: Fix link status reporting
  net: thunderx: Fix TL4 configuration for secondary Qsets

 drivers/net/ethernet/cavium/thunder/nic_main.c| 16 -
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 86 +++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h |  2 +
 3 files changed, 70 insertions(+), 34 deletions(-)

-- 
2.7.4



[PATCH 0/2] net: thunderx: Miscellaneous fixes

2016-06-22 Thread sunil . kovvuri
From: Sunil Goutham 

This 2 patch series fixes issues w.r.t physical link status 
reporting and transmit datapath configuration for 
secondary qsets.

Sunil Goutham (2):
  net: thunderx: Fix link status reporting
  net: thunderx: Fix TL4 configuration for secondary Qsets

 drivers/net/ethernet/cavium/thunder/nic_main.c| 16 -
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 86 +++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h |  2 +
 3 files changed, 70 insertions(+), 34 deletions(-)

-- 
2.7.4



[PATCH v5] tools/perf: Fix the mask in regs_dump__printf and print_sample_iregs

2016-06-22 Thread Madhavan Srinivasan
When decoding the perf_regs mask in regs_dump__printf(),
we loop through the mask using find_first_bit and find_next_bit functions.
"mask" is of type "u64", but sent as a "unsigned long *" to
lib functions along with sizeof().

While the exisitng code works fine in most of the case,
the logic is broken when using a 32bit perf on a 64bit kernel (Big Endian).
When reading u64 using (u32 *)()[0], perf (lib/find_*_bit()) assumes it gets
lower 32bits of u64 which is wrong. Proposed fix is to swap the words
of the u64 to handle this case. This is _not_ endianess swap.

Suggested-by: Yury Norov 
Cc: Yury Norov 
Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexander Shishkin 
Cc: Jiri Olsa 
Cc: Adrian Hunter 
Cc: Kan Liang 
Cc: Wang Nan 
Cc: Michael Ellerman 
Signed-off-by: Madhavan Srinivasan 
---
Changelog v4:
1) Removed the new macro and resued the DECLARE_BITMAP

Changelog v3:
1)Moved the swap function to lib/bitmap.c
2)Added a macro for declaration
3)Added the comments

Changelog v2:
1)Moved the swap code to a common function
2)Added more comments in the code

Changelog v1:
1)updated commit message and patch subject
2)Add the fix to print_sample_iregs() in builtin-script.c

 tools/include/linux/bitmap.h |  2 ++
 tools/lib/bitmap.c   | 18 ++
 tools/perf/builtin-script.c  |  4 +++-
 tools/perf/util/session.c|  4 +++-
 4 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
index 28f5493da491..5e98525387dc 100644
--- a/tools/include/linux/bitmap.h
+++ b/tools/include/linux/bitmap.h
@@ -2,6 +2,7 @@
 #define _PERF_BITOPS_H
 
 #include 
+#include 
 #include 
 
 #define DECLARE_BITMAP(name,bits) \
@@ -10,6 +11,7 @@
 int __bitmap_weight(const unsigned long *bitmap, int bits);
 void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
 const unsigned long *bitmap2, int bits);
+void bitmap_from_u64(unsigned long *dst, u64 mask);
 
 #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
 
diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c
index 0a1adcfd..464a0cc63e6a 100644
--- a/tools/lib/bitmap.c
+++ b/tools/lib/bitmap.c
@@ -29,3 +29,21 @@ void __bitmap_or(unsigned long *dst, const unsigned long 
*bitmap1,
for (k = 0; k < nr; k++)
dst[k] = bitmap1[k] | bitmap2[k];
 }
+
+/*
+ * bitmap_from_u64 - Check and swap words within u64.
+ *  @mask: source bitmap
+ *  @dst:  destination bitmap
+ *
+ * In 32 bit big endian userspace on a 64bit kernel, 'unsigned long' is 32 
bits.
+ * When reading u64 using (u32 *)()[0] and (u32 *)()[1],
+ * we will get wrong value for the mask. That is "(u32 *)()[0]"
+ * gets upper 32 bits of u64, but perf may expect lower 32bits of u64.
+ */
+void bitmap_from_u64(unsigned long *dst, u64 mask)
+{
+   dst[0] = mask & ULONG_MAX;
+
+   if (sizeof(mask) > sizeof(unsigned long))
+   dst[1] = mask >> 32;
+}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index e3ce2f34d3ad..132a4bb70c31 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -412,11 +412,13 @@ static void print_sample_iregs(struct perf_sample *sample,
struct regs_dump *regs = >intr_regs;
uint64_t mask = attr->sample_regs_intr;
unsigned i = 0, r;
+   DECLARE_BITMAP(_mask, 64);
 
if (!regs)
return;
 
-   for_each_set_bit(r, (unsigned long *) , sizeof(mask) * 8) {
+   bitmap_from_u64(_mask, mask);
+   for_each_set_bit(r, _mask, sizeof(mask) * 8) {
u64 val = regs->regs[i++];
printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 5214974e841a..3576bf13 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -940,8 +940,10 @@ static void branch_stack__printf(struct perf_sample 
*sample)
 static void regs_dump__printf(u64 mask, u64 *regs)
 {
unsigned rid, i = 0;
+   DECLARE_BITMAP(_mask, 64);
 
-   for_each_set_bit(rid, (unsigned long *) , sizeof(mask) * 8) {
+   bitmap_from_u64(_mask, mask);
+   for_each_set_bit(rid, _mask, sizeof(mask) * 8) {
u64 val = regs[i++];
 
printf(" %-5s 0x%" PRIx64 "\n",
-- 
1.9.1



[PATCH v5] tools/perf: Fix the mask in regs_dump__printf and print_sample_iregs

2016-06-22 Thread Madhavan Srinivasan
When decoding the perf_regs mask in regs_dump__printf(),
we loop through the mask using find_first_bit and find_next_bit functions.
"mask" is of type "u64", but sent as a "unsigned long *" to
lib functions along with sizeof().

While the exisitng code works fine in most of the case,
the logic is broken when using a 32bit perf on a 64bit kernel (Big Endian).
When reading u64 using (u32 *)()[0], perf (lib/find_*_bit()) assumes it gets
lower 32bits of u64 which is wrong. Proposed fix is to swap the words
of the u64 to handle this case. This is _not_ endianess swap.

Suggested-by: Yury Norov 
Cc: Yury Norov 
Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexander Shishkin 
Cc: Jiri Olsa 
Cc: Adrian Hunter 
Cc: Kan Liang 
Cc: Wang Nan 
Cc: Michael Ellerman 
Signed-off-by: Madhavan Srinivasan 
---
Changelog v4:
1) Removed the new macro and resued the DECLARE_BITMAP

Changelog v3:
1)Moved the swap function to lib/bitmap.c
2)Added a macro for declaration
3)Added the comments

Changelog v2:
1)Moved the swap code to a common function
2)Added more comments in the code

Changelog v1:
1)updated commit message and patch subject
2)Add the fix to print_sample_iregs() in builtin-script.c

 tools/include/linux/bitmap.h |  2 ++
 tools/lib/bitmap.c   | 18 ++
 tools/perf/builtin-script.c  |  4 +++-
 tools/perf/util/session.c|  4 +++-
 4 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
index 28f5493da491..5e98525387dc 100644
--- a/tools/include/linux/bitmap.h
+++ b/tools/include/linux/bitmap.h
@@ -2,6 +2,7 @@
 #define _PERF_BITOPS_H
 
 #include 
+#include 
 #include 
 
 #define DECLARE_BITMAP(name,bits) \
@@ -10,6 +11,7 @@
 int __bitmap_weight(const unsigned long *bitmap, int bits);
 void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
 const unsigned long *bitmap2, int bits);
+void bitmap_from_u64(unsigned long *dst, u64 mask);
 
 #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
 
diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c
index 0a1adcfd..464a0cc63e6a 100644
--- a/tools/lib/bitmap.c
+++ b/tools/lib/bitmap.c
@@ -29,3 +29,21 @@ void __bitmap_or(unsigned long *dst, const unsigned long 
*bitmap1,
for (k = 0; k < nr; k++)
dst[k] = bitmap1[k] | bitmap2[k];
 }
+
+/*
+ * bitmap_from_u64 - Check and swap words within u64.
+ *  @mask: source bitmap
+ *  @dst:  destination bitmap
+ *
+ * In 32 bit big endian userspace on a 64bit kernel, 'unsigned long' is 32 
bits.
+ * When reading u64 using (u32 *)()[0] and (u32 *)()[1],
+ * we will get wrong value for the mask. That is "(u32 *)()[0]"
+ * gets upper 32 bits of u64, but perf may expect lower 32bits of u64.
+ */
+void bitmap_from_u64(unsigned long *dst, u64 mask)
+{
+   dst[0] = mask & ULONG_MAX;
+
+   if (sizeof(mask) > sizeof(unsigned long))
+   dst[1] = mask >> 32;
+}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index e3ce2f34d3ad..132a4bb70c31 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -412,11 +412,13 @@ static void print_sample_iregs(struct perf_sample *sample,
struct regs_dump *regs = >intr_regs;
uint64_t mask = attr->sample_regs_intr;
unsigned i = 0, r;
+   DECLARE_BITMAP(_mask, 64);
 
if (!regs)
return;
 
-   for_each_set_bit(r, (unsigned long *) , sizeof(mask) * 8) {
+   bitmap_from_u64(_mask, mask);
+   for_each_set_bit(r, _mask, sizeof(mask) * 8) {
u64 val = regs->regs[i++];
printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 5214974e841a..3576bf13 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -940,8 +940,10 @@ static void branch_stack__printf(struct perf_sample 
*sample)
 static void regs_dump__printf(u64 mask, u64 *regs)
 {
unsigned rid, i = 0;
+   DECLARE_BITMAP(_mask, 64);
 
-   for_each_set_bit(rid, (unsigned long *) , sizeof(mask) * 8) {
+   bitmap_from_u64(_mask, mask);
+   for_each_set_bit(rid, _mask, sizeof(mask) * 8) {
u64 val = regs[i++];
 
printf(" %-5s 0x%" PRIx64 "\n",
-- 
1.9.1



Re: [PATCH v3 3/9] kexec_file: Factor out kexec_locate_mem_hole from kexec_add_buffer.

2016-06-22 Thread Dave Young


- Original Message -
From: "Dave Young" 
To: "Thiago Jung Bauermann" 
Cc: linuxppc-...@lists.ozlabs.org, ke...@lists.infradead.org, 
linux-kernel@vger.kernel.org, "Eric Biederman" 
Sent: Thursday, June 23, 2016 10:30:52 AM
Subject: Re: [PATCH v3 3/9] kexec_file: Factor out kexec_locate_mem_hole from 
kexec_add_buffer.

On 06/22/16 at 08:34pm, Thiago Jung Bauermann wrote:
> Am Mittwoch, 22 Juni 2016, 18:18:01 schrieb Dave Young:
> > On 06/21/16 at 04:48pm, Thiago Jung Bauermann wrote:
> > > +/**
> > > + * kexec_locate_mem_hole - find free memory to load segment or use in
> > > purgatory + * @image: kexec image being updated.
> > > + * @size:Memory size.
> > > + * @align:   Minimum alignment needed.
> > > + * @min_addr:Minimum starting address.
> > > + * @max_addr:Maximum end address.
> > > + * @top_down Find the highest free memory region?
> > > + * @addr On success, will have start address of the memory region
> > > found.
> > > + *
> > > + * Return: 0 on success, negative errno on error.
> > > + */
> > > +int kexec_locate_mem_hole(struct kimage *image, unsigned long size,
> > > +   unsigned long align, unsigned long min_addr,
> > > +   unsigned long max_addr, bool top_down,
> > > +   unsigned long *addr)
> > > +{
> > > + int ret;
> > > + struct kexec_buf buf;
> > > +
> > > + memset(, 0, sizeof(struct kexec_buf));
> > > + buf.image = image;
> > > +
> > > + buf.memsz = size;
> > > + buf.buf_align = align;
> > > + buf.buf_min = min_addr;
> > > + buf.buf_max = max_addr;
> > > + buf.top_down = top_down;
> > 
> > Since patch 2/9 moved kexec_buf from internal header file to kexec.h it
> > will be natural to passing a kexec_buf pointer intead of passing all
> > these arguments in kexec_locate_mem_hole.
> > 
> > kbuf.mem can be used for addr.
> 
> Ok. What about this version?
> -- 
> []'s
> Thiago Jung Bauermann
> IBM Linux Technology Center
> 
> 
> Subject: [PATCH 3/9] kexec_file: Factor out kexec_locate_mem_hole from
>  kexec_add_buffer.
> 
> kexec_locate_mem_hole will be used by the PowerPC kexec_file_load
> implementation to find free memory for the purgatory stack.
> 
> Signed-off-by: Thiago Jung Bauermann 
> Cc: Eric Biederman 
> Cc: Dave Young 
> Cc: ke...@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> ---
>  include/linux/kexec.h | 12 +---
>  kernel/kexec_file.c   | 25 -
>  2 files changed, 29 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> index 3d91bcfc180d..e8b099da47f5 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -147,9 +147,14 @@ struct kexec_file_ops {
>  #endif
>  };
>  
> -/*
> - * Keeps track of buffer parameters as provided by caller for requesting
> - * memory placement of buffer.
> +/**
> + * struct kexec_buf - parameters for finding a place for a buffer in memory
> + * @image:   kexec image in which memory to search.
> + * @size:Memory size for the buffer.
> + * @align:   Minimum alignment needed.
> + * @min_addr:Minimum starting address.
> + * @max_addr:Maximum end address.
> + * @top_down:Find the highest free memory region?

Hmm, hold on. For declaring a struct in a header file, comment should be
just after each fields, like below, your format is for a function instead:
struct pci_slot {
struct pci_bus *bus;/* The bus this slot is on */
struct list_head list;  /* node in list of slots on this bus */
struct hotplug_slot *hotplug;   /* Hotplug info (migrate over time) */
unsigned char number;   /* PCI_SLOT(pci_dev->devfn) */
struct kobject kobj;
};

BTW, what is @size? there's no size field in kexec_buf. I think it is not
necessary to add these comment, they are easy to understand. If you really
want, please rewrite them correctly, for example "image" description is wrong.
It is not only for searching memory only, top_down description is also bad.

Thanks
Dave


Re: [PATCH v3 3/9] kexec_file: Factor out kexec_locate_mem_hole from kexec_add_buffer.

2016-06-22 Thread Dave Young


- Original Message -
From: "Dave Young" 
To: "Thiago Jung Bauermann" 
Cc: linuxppc-...@lists.ozlabs.org, ke...@lists.infradead.org, 
linux-kernel@vger.kernel.org, "Eric Biederman" 
Sent: Thursday, June 23, 2016 10:30:52 AM
Subject: Re: [PATCH v3 3/9] kexec_file: Factor out kexec_locate_mem_hole from 
kexec_add_buffer.

On 06/22/16 at 08:34pm, Thiago Jung Bauermann wrote:
> Am Mittwoch, 22 Juni 2016, 18:18:01 schrieb Dave Young:
> > On 06/21/16 at 04:48pm, Thiago Jung Bauermann wrote:
> > > +/**
> > > + * kexec_locate_mem_hole - find free memory to load segment or use in
> > > purgatory + * @image: kexec image being updated.
> > > + * @size:Memory size.
> > > + * @align:   Minimum alignment needed.
> > > + * @min_addr:Minimum starting address.
> > > + * @max_addr:Maximum end address.
> > > + * @top_down Find the highest free memory region?
> > > + * @addr On success, will have start address of the memory region
> > > found.
> > > + *
> > > + * Return: 0 on success, negative errno on error.
> > > + */
> > > +int kexec_locate_mem_hole(struct kimage *image, unsigned long size,
> > > +   unsigned long align, unsigned long min_addr,
> > > +   unsigned long max_addr, bool top_down,
> > > +   unsigned long *addr)
> > > +{
> > > + int ret;
> > > + struct kexec_buf buf;
> > > +
> > > + memset(, 0, sizeof(struct kexec_buf));
> > > + buf.image = image;
> > > +
> > > + buf.memsz = size;
> > > + buf.buf_align = align;
> > > + buf.buf_min = min_addr;
> > > + buf.buf_max = max_addr;
> > > + buf.top_down = top_down;
> > 
> > Since patch 2/9 moved kexec_buf from internal header file to kexec.h it
> > will be natural to passing a kexec_buf pointer intead of passing all
> > these arguments in kexec_locate_mem_hole.
> > 
> > kbuf.mem can be used for addr.
> 
> Ok. What about this version?
> -- 
> []'s
> Thiago Jung Bauermann
> IBM Linux Technology Center
> 
> 
> Subject: [PATCH 3/9] kexec_file: Factor out kexec_locate_mem_hole from
>  kexec_add_buffer.
> 
> kexec_locate_mem_hole will be used by the PowerPC kexec_file_load
> implementation to find free memory for the purgatory stack.
> 
> Signed-off-by: Thiago Jung Bauermann 
> Cc: Eric Biederman 
> Cc: Dave Young 
> Cc: ke...@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> ---
>  include/linux/kexec.h | 12 +---
>  kernel/kexec_file.c   | 25 -
>  2 files changed, 29 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> index 3d91bcfc180d..e8b099da47f5 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -147,9 +147,14 @@ struct kexec_file_ops {
>  #endif
>  };
>  
> -/*
> - * Keeps track of buffer parameters as provided by caller for requesting
> - * memory placement of buffer.
> +/**
> + * struct kexec_buf - parameters for finding a place for a buffer in memory
> + * @image:   kexec image in which memory to search.
> + * @size:Memory size for the buffer.
> + * @align:   Minimum alignment needed.
> + * @min_addr:Minimum starting address.
> + * @max_addr:Maximum end address.
> + * @top_down:Find the highest free memory region?

Hmm, hold on. For declaring a struct in a header file, comment should be
just after each fields, like below, your format is for a function instead:
struct pci_slot {
struct pci_bus *bus;/* The bus this slot is on */
struct list_head list;  /* node in list of slots on this bus */
struct hotplug_slot *hotplug;   /* Hotplug info (migrate over time) */
unsigned char number;   /* PCI_SLOT(pci_dev->devfn) */
struct kobject kobj;
};

BTW, what is @size? there's no size field in kexec_buf. I think it is not
necessary to add these comment, they are easy to understand. If you really
want, please rewrite them correctly, for example "image" description is wrong.
It is not only for searching memory only, top_down description is also bad.

Thanks
Dave


Re: [PATCH net-next 10/19] net: hns: bugfix about pfc pause frame statistics

2016-06-22 Thread Yisen Zhuang


在 2016/6/22 17:41, Andy Shevchenko 写道:
> On Wed, 2016-06-22 at 09:43 +0800, Yisen Zhuang wrote:
>>
>> 在 2016/6/21 18:32, Andy Shevchenko 写道:
>>> On Tue, 2016-06-21 at 11:56 +0800, Yisen Zhuang wrote:
 From: Daode Huang 

 For SoC hip06, PFC pause handled in dsaf, while hip05 in XGMAC,
 so change the statistics of pfc pause in dsaf and remove the old
 pfc pause frame statistics.

>>>  
>>>
 +static char *hns_dsaf_get_node_stats_strings(char *data, int
 node,
 +   struct dsaf_device
 *dsaf_dev)
  {
char *buff = data;
 +  int i;
 +  bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver);
  
snprintf(buff, ETH_GSTRING_LEN, "innod%d_pad_drop_pkts",
 node);
buff = buff + ETH_GSTRING_LEN;
 @@ -2502,6 +2530,18 @@ static char
 *hns_dsaf_get_node_stats_strings(char *data, int node)
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "innod%d_stp_drop_pkts",
 node);
buff = buff + ETH_GSTRING_LEN;
 +  if ((node < DSAF_SERVICE_NW_NUM) && (!is_ver1)) {
>>>
>>> Redundant parens.
>>>
 +  for (i = 0; i < DSAF_PRIO_NR; i++) {
 +  snprintf(buff, ETH_GSTRING_LEN,
 +   "inod%d_pfc_prio%d_pkts", node,
 i);
 +  buff = buff + ETH_GSTRING_LEN;
>>>
>>> buff += ...
>>>
 +  }
 +  for (i = 0; i < DSAF_PRIO_NR; i++) {
 +  snprintf(buff, ETH_GSTRING_LEN,
 +   "onod%d_pfc_prio%d_pkts", node,
 i);
 +  buff = buff + ETH_GSTRING_LEN;
>>>
>>> Ditto.
>>>
  {
u64 *p = data;
 +  int i;
struct dsaf_hw_stats *hw_stats = 
> hw_stats[node_num];
 +  bool is_ver1 = AE_IS_VER1(ddev->dsaf_ver);
  
p[0] = hw_stats->pad_drop;
p[1] = hw_stats->man_pkts;
 @@ -2527,8 +2569,16 @@ static u64 *hns_dsaf_get_node_stats(struct
 dsaf_device *ddev, u64 *data,
p[10] = hw_stats->local_addr_false;
p[11] = hw_stats->vlan_drop;
p[12] = hw_stats->stp_drop;
 -  p[13] = hw_stats->tx_pkts;
 +  if ((node_num < DSAF_SERVICE_NW_NUM) && (!is_ver1)) {
 +  for (i = 0; i < DSAF_PRIO_NR; i++) {
 +  p[13 + i] = hw_stats->rx_pfc[i];
 +  p[13 + i + DSAF_PRIO_NR] = hw_stats-
> tx_pfc[i];
 +  }
>>>
>>> Two different approaches how to assign data. Above uses 2 for-loops,
>>> here you put everything to one.
>>
>> Above cann't be merged to 1 for-loop, because lenght of the string is
>> unknowable.
> 
> It doesn't matter since you are incrementing start position by
> constant. 
> 
> snprintf(buff, ETH_GSTRING_LEN, "inod%d_pfc_prio%d_pkts", node, i);
> snprintf(buff, ETH_GSTRING_LEN, "onod%d_pfc_prio%d_pkts", node, i);
> 
> Same approach as below can be used
> 
> snprintf(buff + 0 * ETH_GSTRING_LEN * DSAF_PRIO_NR, ETH_GSTRING_LEN, ...
> snprintf(buff + 1 * ETH_GSTRING_LEN * DSAF_PRIO_NR, ETH_GSTRING_LEN, ...
> 
> Of course to make it less verbose you may add new definition(s) and/ or
> variable(s).
> 
>>
>> And here we put everything to one to reduce codes.
>>
> 
> I would suggest to use following pattern for such lines
> p[13 + i + 0 * DSAF_PRIO_NR] = hw_stats->rx_pfc[i];
> p[13 + i + 1 * DSAF_PRIO_NR] = hw_stats->tx_pfc[i];
> 
> That's allow reader to see what are you doing here.
> 
> P.S. This is for the future patches since current is already applied.

Hi Andy,

Many thanks for you suggestions. I will fix it with a new patch.

Thanks,

Yisen

> 



Re: [PATCH net-next 10/19] net: hns: bugfix about pfc pause frame statistics

2016-06-22 Thread Yisen Zhuang


在 2016/6/22 17:41, Andy Shevchenko 写道:
> On Wed, 2016-06-22 at 09:43 +0800, Yisen Zhuang wrote:
>>
>> 在 2016/6/21 18:32, Andy Shevchenko 写道:
>>> On Tue, 2016-06-21 at 11:56 +0800, Yisen Zhuang wrote:
 From: Daode Huang 

 For SoC hip06, PFC pause handled in dsaf, while hip05 in XGMAC,
 so change the statistics of pfc pause in dsaf and remove the old
 pfc pause frame statistics.

>>>  
>>>
 +static char *hns_dsaf_get_node_stats_strings(char *data, int
 node,
 +   struct dsaf_device
 *dsaf_dev)
  {
char *buff = data;
 +  int i;
 +  bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver);
  
snprintf(buff, ETH_GSTRING_LEN, "innod%d_pad_drop_pkts",
 node);
buff = buff + ETH_GSTRING_LEN;
 @@ -2502,6 +2530,18 @@ static char
 *hns_dsaf_get_node_stats_strings(char *data, int node)
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "innod%d_stp_drop_pkts",
 node);
buff = buff + ETH_GSTRING_LEN;
 +  if ((node < DSAF_SERVICE_NW_NUM) && (!is_ver1)) {
>>>
>>> Redundant parens.
>>>
 +  for (i = 0; i < DSAF_PRIO_NR; i++) {
 +  snprintf(buff, ETH_GSTRING_LEN,
 +   "inod%d_pfc_prio%d_pkts", node,
 i);
 +  buff = buff + ETH_GSTRING_LEN;
>>>
>>> buff += ...
>>>
 +  }
 +  for (i = 0; i < DSAF_PRIO_NR; i++) {
 +  snprintf(buff, ETH_GSTRING_LEN,
 +   "onod%d_pfc_prio%d_pkts", node,
 i);
 +  buff = buff + ETH_GSTRING_LEN;
>>>
>>> Ditto.
>>>
  {
u64 *p = data;
 +  int i;
struct dsaf_hw_stats *hw_stats = 
> hw_stats[node_num];
 +  bool is_ver1 = AE_IS_VER1(ddev->dsaf_ver);
  
p[0] = hw_stats->pad_drop;
p[1] = hw_stats->man_pkts;
 @@ -2527,8 +2569,16 @@ static u64 *hns_dsaf_get_node_stats(struct
 dsaf_device *ddev, u64 *data,
p[10] = hw_stats->local_addr_false;
p[11] = hw_stats->vlan_drop;
p[12] = hw_stats->stp_drop;
 -  p[13] = hw_stats->tx_pkts;
 +  if ((node_num < DSAF_SERVICE_NW_NUM) && (!is_ver1)) {
 +  for (i = 0; i < DSAF_PRIO_NR; i++) {
 +  p[13 + i] = hw_stats->rx_pfc[i];
 +  p[13 + i + DSAF_PRIO_NR] = hw_stats-
> tx_pfc[i];
 +  }
>>>
>>> Two different approaches how to assign data. Above uses 2 for-loops,
>>> here you put everything to one.
>>
>> Above cann't be merged to 1 for-loop, because lenght of the string is
>> unknowable.
> 
> It doesn't matter since you are incrementing start position by
> constant. 
> 
> snprintf(buff, ETH_GSTRING_LEN, "inod%d_pfc_prio%d_pkts", node, i);
> snprintf(buff, ETH_GSTRING_LEN, "onod%d_pfc_prio%d_pkts", node, i);
> 
> Same approach as below can be used
> 
> snprintf(buff + 0 * ETH_GSTRING_LEN * DSAF_PRIO_NR, ETH_GSTRING_LEN, ...
> snprintf(buff + 1 * ETH_GSTRING_LEN * DSAF_PRIO_NR, ETH_GSTRING_LEN, ...
> 
> Of course to make it less verbose you may add new definition(s) and/ or
> variable(s).
> 
>>
>> And here we put everything to one to reduce codes.
>>
> 
> I would suggest to use following pattern for such lines
> p[13 + i + 0 * DSAF_PRIO_NR] = hw_stats->rx_pfc[i];
> p[13 + i + 1 * DSAF_PRIO_NR] = hw_stats->tx_pfc[i];
> 
> That's allow reader to see what are you doing here.
> 
> P.S. This is for the future patches since current is already applied.

Hi Andy,

Many thanks for you suggestions. I will fix it with a new patch.

Thanks,

Yisen

> 



Re: [PATCH v3 2/2] pci/aer: interrupt fixup in the quirk

2016-06-22 Thread Dongdong Liu



在 2016/6/14 16:24, Po Liu 写道:

On some platforms, root port doesn't support MSI/MSI-X/INTx in RC mode.
When chip support the aer interrupt with none MSI/MSI-X/INTx mode,
maybe there is interrupt line for aer pme etc. Search the interrupt
number in the fdt file. Then fixup the dev->irq with it.

Signed-off-by: Po Liu 
---
changes for V3:
- Move to quirk;
- Only correct the irq in RC mode;

  drivers/pci/quirks.c | 29 +
  1 file changed, 29 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index ee72ebe..8b39cce 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -25,6 +25,7 @@
  #include 
  #include 
  #include 
+#include 
  #include /* isa_dma_bridge_buggy */
  #include "pci.h"

@@ -4419,3 +4420,31 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev)
}
  }
  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap);
+
+/* If root port doesn't support MSI/MSI-X/INTx in RC mode,
+ * but use standalone irq. Read the device tree for the aer
+ * interrupt number.
+ */
+static void quirk_aer_interrupt(struct pci_dev *dev)
+{
+   int ret;
+   u8 header_type;
+   struct device_node *np = NULL;
+
+   /* Only for the RC mode device */
+   pci_read_config_byte(dev, PCI_HEADER_TYPE, _type);
+   if ((header_type & 0x7F) != PCI_HEADER_TYPE_BRIDGE)
+   return;


How about that it is changed as below.

/* Only for the RC mode device */
if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
return;

Dongdong
Thanks

+
+   if (dev->bus->dev.of_node)
+   np = dev->bus->dev.of_node;
+
+   if (IS_ENABLED(CONFIG_OF_IRQ) && np) {
+   ret = of_irq_get_byname(np, "aer");
+   if (ret > 0) {
+   dev->no_msi = 1;
+   dev->irq = ret;
+   }
+   }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, 
quirk_aer_interrupt);





Re: [PATCH v3 2/2] pci/aer: interrupt fixup in the quirk

2016-06-22 Thread Dongdong Liu



在 2016/6/14 16:24, Po Liu 写道:

On some platforms, root port doesn't support MSI/MSI-X/INTx in RC mode.
When chip support the aer interrupt with none MSI/MSI-X/INTx mode,
maybe there is interrupt line for aer pme etc. Search the interrupt
number in the fdt file. Then fixup the dev->irq with it.

Signed-off-by: Po Liu 
---
changes for V3:
- Move to quirk;
- Only correct the irq in RC mode;

  drivers/pci/quirks.c | 29 +
  1 file changed, 29 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index ee72ebe..8b39cce 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -25,6 +25,7 @@
  #include 
  #include 
  #include 
+#include 
  #include /* isa_dma_bridge_buggy */
  #include "pci.h"

@@ -4419,3 +4420,31 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev)
}
  }
  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap);
+
+/* If root port doesn't support MSI/MSI-X/INTx in RC mode,
+ * but use standalone irq. Read the device tree for the aer
+ * interrupt number.
+ */
+static void quirk_aer_interrupt(struct pci_dev *dev)
+{
+   int ret;
+   u8 header_type;
+   struct device_node *np = NULL;
+
+   /* Only for the RC mode device */
+   pci_read_config_byte(dev, PCI_HEADER_TYPE, _type);
+   if ((header_type & 0x7F) != PCI_HEADER_TYPE_BRIDGE)
+   return;


How about that it is changed as below.

/* Only for the RC mode device */
if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
return;

Dongdong
Thanks

+
+   if (dev->bus->dev.of_node)
+   np = dev->bus->dev.of_node;
+
+   if (IS_ENABLED(CONFIG_OF_IRQ) && np) {
+   ret = of_irq_get_byname(np, "aer");
+   if (ret > 0) {
+   dev->no_msi = 1;
+   dev->irq = ret;
+   }
+   }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, 
quirk_aer_interrupt);





[PATCH v4 2/3] staging: wilc1000: Replace kthread with workqueue for host interface

2016-06-22 Thread Binoy Jayan
Deconstruct the kthread / message_queue logic, replacing it with
create_singlethread_workqueue() / queue_work() setup, by adding a
'struct work_struct' to 'struct host_if_msg'. The current kthread
hostIFthread() is converted to a work queue helper with the name
'host_if_work'.

Signed-off-by: Binoy Jayan 
---
 drivers/staging/wilc1000/TODO |   5 +
 drivers/staging/wilc1000/host_interface.c | 282 --
 2 files changed, 75 insertions(+), 212 deletions(-)

diff --git a/drivers/staging/wilc1000/TODO b/drivers/staging/wilc1000/TODO
index 95199d8..ec93b2e 100644
--- a/drivers/staging/wilc1000/TODO
+++ b/drivers/staging/wilc1000/TODO
@@ -4,6 +4,11 @@ TODO:
 - remove custom debug and tracing functions
 - rework comments and function headers(also coding style)
 - replace all semaphores with mutexes or completions
+- Move handling for each individual members of 'union message_body' out
+  into a separate 'struct work_struct' and completely remove the multiplexer
+  that is currently part of host_if_work(), allowing movement of the
+  implementation of each message handler into the callsite of the function
+  that currently queues the 'host_if_msg'.
 - make spi and sdio components coexist in one build
 - turn compile-time platform configuration (BEAGLE_BOARD,
   PANDA_BOARD, PLAT_WMS8304, PLAT_RK, CUSTOMER_PLATFORM, ...)
diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 2d250c6..242c3d7 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -4,6 +4,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "host_interface.h"
 #include 
 #include 
@@ -211,6 +212,7 @@ struct host_if_msg {
u16 id;
union message_body body;
struct wilc_vif *vif;
+   struct work_struct work;
 };
 
 struct join_bss_param {
@@ -245,7 +247,7 @@ struct join_bss_param {
 static struct host_if_drv *terminated_handle;
 bool wilc_optaining_ip;
 static u8 P2P_LISTEN_STATE;
-static struct task_struct *hif_thread_handler;
+static struct workqueue_struct *hif_workqueue;
 static struct message_queue hif_msg_q;
 static struct completion hif_thread_comp;
 static struct completion hif_driver_comp;
@@ -280,55 +282,7 @@ static struct wilc_vif *join_req_vif;
 static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
 static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent);
-static int wilc_mq_create(struct message_queue *mq);
-static int wilc_mq_send(struct message_queue *mq,
-const void *send_buf, u32 send_buf_size);
-static int wilc_mq_recv(struct message_queue *mq,
-void *recv_buf, u32 recv_buf_size, u32 *recv_len);
-static int wilc_mq_destroy(struct message_queue *mq);
-
-/*!
- *  @authorsyounan
- *  @date  1 Sep 2010
- *  @note  copied from FLO glue implementatuion
- *  @version   1.0
- */
-static int wilc_mq_create(struct message_queue *mq)
-{
-   spin_lock_init(>lock);
-   sema_init(>sem, 0);
-   INIT_LIST_HEAD(>msg_list);
-   mq->recv_count = 0;
-   mq->exiting = false;
-   return 0;
-}
-
-/*!
- *  @authorsyounan
- *  @date  1 Sep 2010
- *  @note  copied from FLO glue implementatuion
- *  @version   1.0
- */
-static int wilc_mq_destroy(struct message_queue *mq)
-{
-   struct message *msg;
-
-   mq->exiting = true;
-
-   /* Release any waiting receiver thread. */
-   while (mq->recv_count > 0) {
-   up(>sem);
-   mq->recv_count--;
-   }
-
-   while (!list_empty(>msg_list)) {
-   msg = list_first_entry(>msg_list, struct message, list);
-   list_del(>list);
-   kfree(msg->buf);
-   }
-
-   return 0;
-}
+static void host_if_work(struct work_struct *work);
 
 /*!
  *  @authorsyounan
@@ -339,92 +293,17 @@ static int wilc_mq_destroy(struct message_queue *mq)
 static int wilc_mq_send(struct message_queue *mq,
const void *send_buf, u32 send_buf_size)
 {
-   unsigned long flags;
-   struct message *new_msg = NULL;
+   struct host_if_msg *new_msg;
 
-   if (!mq || (send_buf_size == 0) || !send_buf)
-   return -EINVAL;
-
-   if (mq->exiting)
-   return -EFAULT;
-
-   /* construct a new message */
-   new_msg = kmalloc(sizeof(*new_msg), GFP_ATOMIC);
+   new_msg = kmemdup(send_buf, sizeof(*new_msg), GFP_ATOMIC);
if (!new_msg)
return -ENOMEM;
 
-   new_msg->len = send_buf_size;
-   INIT_LIST_HEAD(_msg->list);
-   new_msg->buf = kmemdup(send_buf, send_buf_size, GFP_ATOMIC);
-   if (!new_msg->buf) {
-   kfree(new_msg);
-   return -ENOMEM;
-   }
-
-   

[PATCH v4 2/3] staging: wilc1000: Replace kthread with workqueue for host interface

2016-06-22 Thread Binoy Jayan
Deconstruct the kthread / message_queue logic, replacing it with
create_singlethread_workqueue() / queue_work() setup, by adding a
'struct work_struct' to 'struct host_if_msg'. The current kthread
hostIFthread() is converted to a work queue helper with the name
'host_if_work'.

Signed-off-by: Binoy Jayan 
---
 drivers/staging/wilc1000/TODO |   5 +
 drivers/staging/wilc1000/host_interface.c | 282 --
 2 files changed, 75 insertions(+), 212 deletions(-)

diff --git a/drivers/staging/wilc1000/TODO b/drivers/staging/wilc1000/TODO
index 95199d8..ec93b2e 100644
--- a/drivers/staging/wilc1000/TODO
+++ b/drivers/staging/wilc1000/TODO
@@ -4,6 +4,11 @@ TODO:
 - remove custom debug and tracing functions
 - rework comments and function headers(also coding style)
 - replace all semaphores with mutexes or completions
+- Move handling for each individual members of 'union message_body' out
+  into a separate 'struct work_struct' and completely remove the multiplexer
+  that is currently part of host_if_work(), allowing movement of the
+  implementation of each message handler into the callsite of the function
+  that currently queues the 'host_if_msg'.
 - make spi and sdio components coexist in one build
 - turn compile-time platform configuration (BEAGLE_BOARD,
   PANDA_BOARD, PLAT_WMS8304, PLAT_RK, CUSTOMER_PLATFORM, ...)
diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 2d250c6..242c3d7 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -4,6 +4,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "host_interface.h"
 #include 
 #include 
@@ -211,6 +212,7 @@ struct host_if_msg {
u16 id;
union message_body body;
struct wilc_vif *vif;
+   struct work_struct work;
 };
 
 struct join_bss_param {
@@ -245,7 +247,7 @@ struct join_bss_param {
 static struct host_if_drv *terminated_handle;
 bool wilc_optaining_ip;
 static u8 P2P_LISTEN_STATE;
-static struct task_struct *hif_thread_handler;
+static struct workqueue_struct *hif_workqueue;
 static struct message_queue hif_msg_q;
 static struct completion hif_thread_comp;
 static struct completion hif_driver_comp;
@@ -280,55 +282,7 @@ static struct wilc_vif *join_req_vif;
 static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
 static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent);
-static int wilc_mq_create(struct message_queue *mq);
-static int wilc_mq_send(struct message_queue *mq,
-const void *send_buf, u32 send_buf_size);
-static int wilc_mq_recv(struct message_queue *mq,
-void *recv_buf, u32 recv_buf_size, u32 *recv_len);
-static int wilc_mq_destroy(struct message_queue *mq);
-
-/*!
- *  @authorsyounan
- *  @date  1 Sep 2010
- *  @note  copied from FLO glue implementatuion
- *  @version   1.0
- */
-static int wilc_mq_create(struct message_queue *mq)
-{
-   spin_lock_init(>lock);
-   sema_init(>sem, 0);
-   INIT_LIST_HEAD(>msg_list);
-   mq->recv_count = 0;
-   mq->exiting = false;
-   return 0;
-}
-
-/*!
- *  @authorsyounan
- *  @date  1 Sep 2010
- *  @note  copied from FLO glue implementatuion
- *  @version   1.0
- */
-static int wilc_mq_destroy(struct message_queue *mq)
-{
-   struct message *msg;
-
-   mq->exiting = true;
-
-   /* Release any waiting receiver thread. */
-   while (mq->recv_count > 0) {
-   up(>sem);
-   mq->recv_count--;
-   }
-
-   while (!list_empty(>msg_list)) {
-   msg = list_first_entry(>msg_list, struct message, list);
-   list_del(>list);
-   kfree(msg->buf);
-   }
-
-   return 0;
-}
+static void host_if_work(struct work_struct *work);
 
 /*!
  *  @authorsyounan
@@ -339,92 +293,17 @@ static int wilc_mq_destroy(struct message_queue *mq)
 static int wilc_mq_send(struct message_queue *mq,
const void *send_buf, u32 send_buf_size)
 {
-   unsigned long flags;
-   struct message *new_msg = NULL;
+   struct host_if_msg *new_msg;
 
-   if (!mq || (send_buf_size == 0) || !send_buf)
-   return -EINVAL;
-
-   if (mq->exiting)
-   return -EFAULT;
-
-   /* construct a new message */
-   new_msg = kmalloc(sizeof(*new_msg), GFP_ATOMIC);
+   new_msg = kmemdup(send_buf, sizeof(*new_msg), GFP_ATOMIC);
if (!new_msg)
return -ENOMEM;
 
-   new_msg->len = send_buf_size;
-   INIT_LIST_HEAD(_msg->list);
-   new_msg->buf = kmemdup(send_buf, send_buf_size, GFP_ATOMIC);
-   if (!new_msg->buf) {
-   kfree(new_msg);
-   return -ENOMEM;
-   }
-
-   spin_lock_irqsave(>lock, flags);

[PATCH v4 3/3] staging: wilc1000: Change interface wilc_mq_send to wilc_enqueue_cmd

2016-06-22 Thread Binoy Jayan
Replace the interface 'wilc_mq_send' with 'wilc_enqueue_cmd'
and remove the now unused structures 'message' and 'message_queue'.
Restructure switch statement in the work queue helper function
host_if_work and remove unwanted indentation.

Signed-off-by: Binoy Jayan 
---
 drivers/staging/wilc1000/host_interface.c | 333 ++
 1 file changed, 158 insertions(+), 175 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 242c3d7..9c70318 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -60,20 +60,6 @@
 #define TCP_ACK_FILTER_LINK_SPEED_THRESH   54
 #define DEFAULT_LINK_SPEED 72
 
-struct message {
-   void *buf;
-   u32 len;
-   struct list_head list;
-};
-
-struct message_queue {
-   struct semaphore sem;
-   spinlock_t lock;
-   bool exiting;
-   u32 recv_count;
-   struct list_head msg_list;
-};
-
 struct host_if_wpa_attr {
u8 *key;
const u8 *mac_addr;
@@ -248,7 +234,6 @@ static struct host_if_drv *terminated_handle;
 bool wilc_optaining_ip;
 static u8 P2P_LISTEN_STATE;
 static struct workqueue_struct *hif_workqueue;
-static struct message_queue hif_msg_q;
 static struct completion hif_thread_comp;
 static struct completion hif_driver_comp;
 static struct completion hif_wait_response;
@@ -290,12 +275,11 @@ static void host_if_work(struct work_struct *work);
  *  @note  copied from FLO glue implementatuion
  *  @version   1.0
  */
-static int wilc_mq_send(struct message_queue *mq,
-   const void *send_buf, u32 send_buf_size)
+static int wilc_enqueue_cmd(struct host_if_msg *msg)
 {
struct host_if_msg *new_msg;
 
-   new_msg = kmemdup(send_buf, sizeof(*new_msg), GFP_ATOMIC);
+   new_msg = kmemdup(msg, sizeof(*new_msg), GFP_ATOMIC);
if (!new_msg)
return -ENOMEM;
 
@@ -2404,7 +2388,7 @@ static void ListenTimerCB(unsigned long arg)
msg.vif = vif;
msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
 
-   result = wilc_mq_send(_msg_q, , sizeof(struct host_if_msg));
+   result = wilc_enqueue_cmd();
if (result)
netdev_err(vif->ndev, "wilc_mq_send fail\n");
 }
@@ -2514,160 +2498,159 @@ static void host_if_work(struct work_struct *work)
 
if (msg->id == HOST_IF_MSG_CONNECT &&
msg->vif->hif_drv->usr_scan_req.scan_result) {
-   wilc_mq_send(_msg_q, msg, sizeof(struct host_if_msg));
+   wilc_enqueue_cmd(msg);
usleep_range(2 * 1000, 2 * 1000);
-   } else {
-
-   switch (msg->id) {
-   case HOST_IF_MSG_SCAN:
-   handle_scan(msg->vif, >body.scan_info);
-   break;
-
-   case HOST_IF_MSG_CONNECT:
-   Handle_Connect(msg->vif, >body.con_info);
-   break;
+   goto free_msg;
+   }
+   switch (msg->id) {
+   case HOST_IF_MSG_SCAN:
+   handle_scan(msg->vif, >body.scan_info);
+   break;
 
-   case HOST_IF_MSG_RCVD_NTWRK_INFO:
-   Handle_RcvdNtwrkInfo(msg->vif, >body.net_info);
-   break;
+   case HOST_IF_MSG_CONNECT:
+   Handle_Connect(msg->vif, >body.con_info);
+   break;
 
-   case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
-   Handle_RcvdGnrlAsyncInfo(msg->vif,
->body.async_info);
-   break;
+   case HOST_IF_MSG_RCVD_NTWRK_INFO:
+   Handle_RcvdNtwrkInfo(msg->vif, >body.net_info);
+   break;
 
-   case HOST_IF_MSG_KEY:
-   Handle_Key(msg->vif, >body.key_info);
-   break;
+   case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
+   Handle_RcvdGnrlAsyncInfo(msg->vif,
+>body.async_info);
+   break;
 
-   case HOST_IF_MSG_CFG_PARAMS:
-   handle_cfg_param(msg->vif, >body.cfg_info);
-   break;
+   case HOST_IF_MSG_KEY:
+   Handle_Key(msg->vif, >body.key_info);
+   break;
 
-   case HOST_IF_MSG_SET_CHANNEL:
-   handle_set_channel(msg->vif, >body.channel_info);
-   break;
+   case HOST_IF_MSG_CFG_PARAMS:
+   handle_cfg_param(msg->vif, >body.cfg_info);
+   break;
 
-   case HOST_IF_MSG_DISCONNECT:
-   Handle_Disconnect(msg->vif);
-   break;
+   case HOST_IF_MSG_SET_CHANNEL:
+   handle_set_channel(msg->vif, >body.channel_info);
+   break;
 
-   case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
-

[PATCH v4 3/3] staging: wilc1000: Change interface wilc_mq_send to wilc_enqueue_cmd

2016-06-22 Thread Binoy Jayan
Replace the interface 'wilc_mq_send' with 'wilc_enqueue_cmd'
and remove the now unused structures 'message' and 'message_queue'.
Restructure switch statement in the work queue helper function
host_if_work and remove unwanted indentation.

Signed-off-by: Binoy Jayan 
---
 drivers/staging/wilc1000/host_interface.c | 333 ++
 1 file changed, 158 insertions(+), 175 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 242c3d7..9c70318 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -60,20 +60,6 @@
 #define TCP_ACK_FILTER_LINK_SPEED_THRESH   54
 #define DEFAULT_LINK_SPEED 72
 
-struct message {
-   void *buf;
-   u32 len;
-   struct list_head list;
-};
-
-struct message_queue {
-   struct semaphore sem;
-   spinlock_t lock;
-   bool exiting;
-   u32 recv_count;
-   struct list_head msg_list;
-};
-
 struct host_if_wpa_attr {
u8 *key;
const u8 *mac_addr;
@@ -248,7 +234,6 @@ static struct host_if_drv *terminated_handle;
 bool wilc_optaining_ip;
 static u8 P2P_LISTEN_STATE;
 static struct workqueue_struct *hif_workqueue;
-static struct message_queue hif_msg_q;
 static struct completion hif_thread_comp;
 static struct completion hif_driver_comp;
 static struct completion hif_wait_response;
@@ -290,12 +275,11 @@ static void host_if_work(struct work_struct *work);
  *  @note  copied from FLO glue implementatuion
  *  @version   1.0
  */
-static int wilc_mq_send(struct message_queue *mq,
-   const void *send_buf, u32 send_buf_size)
+static int wilc_enqueue_cmd(struct host_if_msg *msg)
 {
struct host_if_msg *new_msg;
 
-   new_msg = kmemdup(send_buf, sizeof(*new_msg), GFP_ATOMIC);
+   new_msg = kmemdup(msg, sizeof(*new_msg), GFP_ATOMIC);
if (!new_msg)
return -ENOMEM;
 
@@ -2404,7 +2388,7 @@ static void ListenTimerCB(unsigned long arg)
msg.vif = vif;
msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
 
-   result = wilc_mq_send(_msg_q, , sizeof(struct host_if_msg));
+   result = wilc_enqueue_cmd();
if (result)
netdev_err(vif->ndev, "wilc_mq_send fail\n");
 }
@@ -2514,160 +2498,159 @@ static void host_if_work(struct work_struct *work)
 
if (msg->id == HOST_IF_MSG_CONNECT &&
msg->vif->hif_drv->usr_scan_req.scan_result) {
-   wilc_mq_send(_msg_q, msg, sizeof(struct host_if_msg));
+   wilc_enqueue_cmd(msg);
usleep_range(2 * 1000, 2 * 1000);
-   } else {
-
-   switch (msg->id) {
-   case HOST_IF_MSG_SCAN:
-   handle_scan(msg->vif, >body.scan_info);
-   break;
-
-   case HOST_IF_MSG_CONNECT:
-   Handle_Connect(msg->vif, >body.con_info);
-   break;
+   goto free_msg;
+   }
+   switch (msg->id) {
+   case HOST_IF_MSG_SCAN:
+   handle_scan(msg->vif, >body.scan_info);
+   break;
 
-   case HOST_IF_MSG_RCVD_NTWRK_INFO:
-   Handle_RcvdNtwrkInfo(msg->vif, >body.net_info);
-   break;
+   case HOST_IF_MSG_CONNECT:
+   Handle_Connect(msg->vif, >body.con_info);
+   break;
 
-   case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
-   Handle_RcvdGnrlAsyncInfo(msg->vif,
->body.async_info);
-   break;
+   case HOST_IF_MSG_RCVD_NTWRK_INFO:
+   Handle_RcvdNtwrkInfo(msg->vif, >body.net_info);
+   break;
 
-   case HOST_IF_MSG_KEY:
-   Handle_Key(msg->vif, >body.key_info);
-   break;
+   case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
+   Handle_RcvdGnrlAsyncInfo(msg->vif,
+>body.async_info);
+   break;
 
-   case HOST_IF_MSG_CFG_PARAMS:
-   handle_cfg_param(msg->vif, >body.cfg_info);
-   break;
+   case HOST_IF_MSG_KEY:
+   Handle_Key(msg->vif, >body.key_info);
+   break;
 
-   case HOST_IF_MSG_SET_CHANNEL:
-   handle_set_channel(msg->vif, >body.channel_info);
-   break;
+   case HOST_IF_MSG_CFG_PARAMS:
+   handle_cfg_param(msg->vif, >body.cfg_info);
+   break;
 
-   case HOST_IF_MSG_DISCONNECT:
-   Handle_Disconnect(msg->vif);
-   break;
+   case HOST_IF_MSG_SET_CHANNEL:
+   handle_set_channel(msg->vif, >body.channel_info);
+   break;
 
-   case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
-   

[PATCH v4 1/3] staging: wilc1000: message_queue: Move code to host interface

2016-06-22 Thread Binoy Jayan
Move the contents of wilc_msgqueue.c and wilc_msgqueue.h into
host_interface.c, remove 'wilc_msgqueue.c' and 'wilc_msgqueue.h'.
This is done so as to restructure the implementation of the kthread
'hostIFthread' using a work queue.

Signed-off-by: Binoy Jayan 
---
 drivers/staging/wilc1000/Makefile |   1 -
 drivers/staging/wilc1000/host_interface.c | 163 +-
 drivers/staging/wilc1000/wilc_msgqueue.c  | 144 --
 drivers/staging/wilc1000/wilc_msgqueue.h  |  28 -
 4 files changed, 162 insertions(+), 174 deletions(-)
 delete mode 100644 drivers/staging/wilc1000/wilc_msgqueue.c
 delete mode 100644 drivers/staging/wilc1000/wilc_msgqueue.h

diff --git a/drivers/staging/wilc1000/Makefile 
b/drivers/staging/wilc1000/Makefile
index acc3f3e..d226283 100644
--- a/drivers/staging/wilc1000/Makefile
+++ b/drivers/staging/wilc1000/Makefile
@@ -6,7 +6,6 @@ ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \
 ccflags-y += -I$(src)/ -DWILC_ASIC_A0 -DWILC_DEBUGFS
 
 wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \
-   wilc_msgqueue.o \
coreconfigurator.o host_interface.o \
wilc_wlan_cfg.o wilc_debugfs.o \
wilc_wlan.o
diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 9535842..2d250c6 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -3,11 +3,13 @@
 #include 
 #include 
 #include 
+#include 
 #include "host_interface.h"
+#include 
+#include 
 #include "coreconfigurator.h"
 #include "wilc_wlan.h"
 #include "wilc_wlan_if.h"
-#include "wilc_msgqueue.h"
 #include 
 #include "wilc_wfi_netdevice.h"
 
@@ -57,6 +59,20 @@
 #define TCP_ACK_FILTER_LINK_SPEED_THRESH   54
 #define DEFAULT_LINK_SPEED 72
 
+struct message {
+   void *buf;
+   u32 len;
+   struct list_head list;
+};
+
+struct message_queue {
+   struct semaphore sem;
+   spinlock_t lock;
+   bool exiting;
+   u32 recv_count;
+   struct list_head msg_list;
+};
+
 struct host_if_wpa_attr {
u8 *key;
const u8 *mac_addr;
@@ -264,6 +280,151 @@ static struct wilc_vif *join_req_vif;
 static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
 static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent);
+static int wilc_mq_create(struct message_queue *mq);
+static int wilc_mq_send(struct message_queue *mq,
+const void *send_buf, u32 send_buf_size);
+static int wilc_mq_recv(struct message_queue *mq,
+void *recv_buf, u32 recv_buf_size, u32 *recv_len);
+static int wilc_mq_destroy(struct message_queue *mq);
+
+/*!
+ *  @authorsyounan
+ *  @date  1 Sep 2010
+ *  @note  copied from FLO glue implementatuion
+ *  @version   1.0
+ */
+static int wilc_mq_create(struct message_queue *mq)
+{
+   spin_lock_init(>lock);
+   sema_init(>sem, 0);
+   INIT_LIST_HEAD(>msg_list);
+   mq->recv_count = 0;
+   mq->exiting = false;
+   return 0;
+}
+
+/*!
+ *  @authorsyounan
+ *  @date  1 Sep 2010
+ *  @note  copied from FLO glue implementatuion
+ *  @version   1.0
+ */
+static int wilc_mq_destroy(struct message_queue *mq)
+{
+   struct message *msg;
+
+   mq->exiting = true;
+
+   /* Release any waiting receiver thread. */
+   while (mq->recv_count > 0) {
+   up(>sem);
+   mq->recv_count--;
+   }
+
+   while (!list_empty(>msg_list)) {
+   msg = list_first_entry(>msg_list, struct message, list);
+   list_del(>list);
+   kfree(msg->buf);
+   }
+
+   return 0;
+}
+
+/*!
+ *  @authorsyounan
+ *  @date  1 Sep 2010
+ *  @note  copied from FLO glue implementatuion
+ *  @version   1.0
+ */
+static int wilc_mq_send(struct message_queue *mq,
+   const void *send_buf, u32 send_buf_size)
+{
+   unsigned long flags;
+   struct message *new_msg = NULL;
+
+   if (!mq || (send_buf_size == 0) || !send_buf)
+   return -EINVAL;
+
+   if (mq->exiting)
+   return -EFAULT;
+
+   /* construct a new message */
+   new_msg = kmalloc(sizeof(*new_msg), GFP_ATOMIC);
+   if (!new_msg)
+   return -ENOMEM;
+
+   new_msg->len = send_buf_size;
+   INIT_LIST_HEAD(_msg->list);
+   new_msg->buf = kmemdup(send_buf, send_buf_size, GFP_ATOMIC);
+   if (!new_msg->buf) {
+   kfree(new_msg);
+   return -ENOMEM;
+   }
+
+   spin_lock_irqsave(>lock, flags);
+
+   /* add it to the message queue */
+   list_add_tail(_msg->list, >msg_list);
+
+ 

[PATCH v4 0/3] *** staging: wilc1000: Replace semaphores ***

2016-06-22 Thread Binoy Jayan
Hi,

Thank you Arnd for patiently reviewing this patch series multiple times and
apologies to everyone for spamming you inboxes with a patch (v3) that does
not even build. It was due to an uncommited change in my git repo before
generating the patch. It is corrected in v4.

This patchset [v4] is part of the second patch series for 'wilc1000'.
The original patch series consisted 7 patches of which only the first 5
are good. The patch 6 and 7 are being worked on in this series
in a different way.

This patch series removes the semaphore 'sem' in 'wilc1000' and also
restructures the implementation of kthread / message_queue logic with
a create_singlethread_workqueue() / queue_work() setup.

These are part of a bigger effort to eliminate all semaphores
from the linux kernel.

They build correctly (individually and as a whole).

NB: The changes are untested

Discussion carried forward from previous patchset [v2]

Rework on the review comments by Arnd w.r.t. v1

struct message_queue can be removed since
 - after the workqueue conversion, mq->sem is no longer needed
 - recv_count is not needed, it just counts the number of entries in the list
 - struct wilc' pointer can be retrieved from the host_if_msg, (vif->wilc)
 - the message list is not needed because we always look only at the
   first entry, except in wilc_mq_destroy(), but it would be better
   to just call destroy_workqueue(), which also drains the remaining work.
 - the exiting flag is also handled by destroy_workqueue()   
 - with everything else gone, the spinlock is also not needed any more.

Do 'kfree' only at the end of 'host_if_work' 

wilc_initialized is always '1' so the conditional 'wilc_mq_send'
in 'hostIFthread' can be removed.

A connect command (HOST_IF_MSG_CONNECT) does not complete while scan is 
ongoing. 
So, the special handling of this command needs to be preserved.

Use create_singlethread_workqueue() instead of alloc_workqueue(), so that
we stay closer to the current behavior by having the thread run only
on one CPU at a time and not having a 'dedicated' thread for each.

Split the patch to seperate interface changes to 'wilc_mq_send'
No easy way found to split the patch to change the interface
'wilc_mq_send' and to 'wilc_enqueue_cmd' as the parameters 
'mq' 'send_buf' and 'send_buf_size' itself are part of the message
queue implementation.

New changes in v3

Rework on the review comments by Arnd w.r.t. v2
 - Remove forward declaration for wilc_enqueue_cmd
 - Change the interface 'wilc_mq_send' in a different patch
 - Avoid change in indentation in host_if_work and move it to
   a different patch

Cannot remove forward declaration of local function 'host_if_work'
   since there is a mutual dependency.

New changes in v4

Remove unused identifier 'hif_msg_q' which causes the build error.

Binoy

Binoy Jayan (3):
  staging: wilc1000: message_queue: Move code to host interface
  staging: wilc1000: Replace kthread with workqueue for host interface
  staging: wilc1000: Change interface wilc_mq_send to wilc_enqueue_cmd

 drivers/staging/wilc1000/Makefile |   1 -
 drivers/staging/wilc1000/TODO |   5 +
 drivers/staging/wilc1000/host_interface.c | 396 +++---
 drivers/staging/wilc1000/wilc_msgqueue.c  | 144 ---
 drivers/staging/wilc1000/wilc_msgqueue.h  |  28 ---
 5 files changed, 204 insertions(+), 370 deletions(-)
 delete mode 100644 drivers/staging/wilc1000/wilc_msgqueue.c
 delete mode 100644 drivers/staging/wilc1000/wilc_msgqueue.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 1/3] staging: wilc1000: message_queue: Move code to host interface

2016-06-22 Thread Binoy Jayan
Move the contents of wilc_msgqueue.c and wilc_msgqueue.h into
host_interface.c, remove 'wilc_msgqueue.c' and 'wilc_msgqueue.h'.
This is done so as to restructure the implementation of the kthread
'hostIFthread' using a work queue.

Signed-off-by: Binoy Jayan 
---
 drivers/staging/wilc1000/Makefile |   1 -
 drivers/staging/wilc1000/host_interface.c | 163 +-
 drivers/staging/wilc1000/wilc_msgqueue.c  | 144 --
 drivers/staging/wilc1000/wilc_msgqueue.h  |  28 -
 4 files changed, 162 insertions(+), 174 deletions(-)
 delete mode 100644 drivers/staging/wilc1000/wilc_msgqueue.c
 delete mode 100644 drivers/staging/wilc1000/wilc_msgqueue.h

diff --git a/drivers/staging/wilc1000/Makefile 
b/drivers/staging/wilc1000/Makefile
index acc3f3e..d226283 100644
--- a/drivers/staging/wilc1000/Makefile
+++ b/drivers/staging/wilc1000/Makefile
@@ -6,7 +6,6 @@ ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \
 ccflags-y += -I$(src)/ -DWILC_ASIC_A0 -DWILC_DEBUGFS
 
 wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \
-   wilc_msgqueue.o \
coreconfigurator.o host_interface.o \
wilc_wlan_cfg.o wilc_debugfs.o \
wilc_wlan.o
diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 9535842..2d250c6 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -3,11 +3,13 @@
 #include 
 #include 
 #include 
+#include 
 #include "host_interface.h"
+#include 
+#include 
 #include "coreconfigurator.h"
 #include "wilc_wlan.h"
 #include "wilc_wlan_if.h"
-#include "wilc_msgqueue.h"
 #include 
 #include "wilc_wfi_netdevice.h"
 
@@ -57,6 +59,20 @@
 #define TCP_ACK_FILTER_LINK_SPEED_THRESH   54
 #define DEFAULT_LINK_SPEED 72
 
+struct message {
+   void *buf;
+   u32 len;
+   struct list_head list;
+};
+
+struct message_queue {
+   struct semaphore sem;
+   spinlock_t lock;
+   bool exiting;
+   u32 recv_count;
+   struct list_head msg_list;
+};
+
 struct host_if_wpa_attr {
u8 *key;
const u8 *mac_addr;
@@ -264,6 +280,151 @@ static struct wilc_vif *join_req_vif;
 static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
 static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
 static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent);
+static int wilc_mq_create(struct message_queue *mq);
+static int wilc_mq_send(struct message_queue *mq,
+const void *send_buf, u32 send_buf_size);
+static int wilc_mq_recv(struct message_queue *mq,
+void *recv_buf, u32 recv_buf_size, u32 *recv_len);
+static int wilc_mq_destroy(struct message_queue *mq);
+
+/*!
+ *  @authorsyounan
+ *  @date  1 Sep 2010
+ *  @note  copied from FLO glue implementatuion
+ *  @version   1.0
+ */
+static int wilc_mq_create(struct message_queue *mq)
+{
+   spin_lock_init(>lock);
+   sema_init(>sem, 0);
+   INIT_LIST_HEAD(>msg_list);
+   mq->recv_count = 0;
+   mq->exiting = false;
+   return 0;
+}
+
+/*!
+ *  @authorsyounan
+ *  @date  1 Sep 2010
+ *  @note  copied from FLO glue implementatuion
+ *  @version   1.0
+ */
+static int wilc_mq_destroy(struct message_queue *mq)
+{
+   struct message *msg;
+
+   mq->exiting = true;
+
+   /* Release any waiting receiver thread. */
+   while (mq->recv_count > 0) {
+   up(>sem);
+   mq->recv_count--;
+   }
+
+   while (!list_empty(>msg_list)) {
+   msg = list_first_entry(>msg_list, struct message, list);
+   list_del(>list);
+   kfree(msg->buf);
+   }
+
+   return 0;
+}
+
+/*!
+ *  @authorsyounan
+ *  @date  1 Sep 2010
+ *  @note  copied from FLO glue implementatuion
+ *  @version   1.0
+ */
+static int wilc_mq_send(struct message_queue *mq,
+   const void *send_buf, u32 send_buf_size)
+{
+   unsigned long flags;
+   struct message *new_msg = NULL;
+
+   if (!mq || (send_buf_size == 0) || !send_buf)
+   return -EINVAL;
+
+   if (mq->exiting)
+   return -EFAULT;
+
+   /* construct a new message */
+   new_msg = kmalloc(sizeof(*new_msg), GFP_ATOMIC);
+   if (!new_msg)
+   return -ENOMEM;
+
+   new_msg->len = send_buf_size;
+   INIT_LIST_HEAD(_msg->list);
+   new_msg->buf = kmemdup(send_buf, send_buf_size, GFP_ATOMIC);
+   if (!new_msg->buf) {
+   kfree(new_msg);
+   return -ENOMEM;
+   }
+
+   spin_lock_irqsave(>lock, flags);
+
+   /* add it to the message queue */
+   list_add_tail(_msg->list, >msg_list);
+
+   

[PATCH v4 0/3] *** staging: wilc1000: Replace semaphores ***

2016-06-22 Thread Binoy Jayan
Hi,

Thank you Arnd for patiently reviewing this patch series multiple times and
apologies to everyone for spamming you inboxes with a patch (v3) that does
not even build. It was due to an uncommited change in my git repo before
generating the patch. It is corrected in v4.

This patchset [v4] is part of the second patch series for 'wilc1000'.
The original patch series consisted 7 patches of which only the first 5
are good. The patch 6 and 7 are being worked on in this series
in a different way.

This patch series removes the semaphore 'sem' in 'wilc1000' and also
restructures the implementation of kthread / message_queue logic with
a create_singlethread_workqueue() / queue_work() setup.

These are part of a bigger effort to eliminate all semaphores
from the linux kernel.

They build correctly (individually and as a whole).

NB: The changes are untested

Discussion carried forward from previous patchset [v2]

Rework on the review comments by Arnd w.r.t. v1

struct message_queue can be removed since
 - after the workqueue conversion, mq->sem is no longer needed
 - recv_count is not needed, it just counts the number of entries in the list
 - struct wilc' pointer can be retrieved from the host_if_msg, (vif->wilc)
 - the message list is not needed because we always look only at the
   first entry, except in wilc_mq_destroy(), but it would be better
   to just call destroy_workqueue(), which also drains the remaining work.
 - the exiting flag is also handled by destroy_workqueue()   
 - with everything else gone, the spinlock is also not needed any more.

Do 'kfree' only at the end of 'host_if_work' 

wilc_initialized is always '1' so the conditional 'wilc_mq_send'
in 'hostIFthread' can be removed.

A connect command (HOST_IF_MSG_CONNECT) does not complete while scan is 
ongoing. 
So, the special handling of this command needs to be preserved.

Use create_singlethread_workqueue() instead of alloc_workqueue(), so that
we stay closer to the current behavior by having the thread run only
on one CPU at a time and not having a 'dedicated' thread for each.

Split the patch to seperate interface changes to 'wilc_mq_send'
No easy way found to split the patch to change the interface
'wilc_mq_send' and to 'wilc_enqueue_cmd' as the parameters 
'mq' 'send_buf' and 'send_buf_size' itself are part of the message
queue implementation.

New changes in v3

Rework on the review comments by Arnd w.r.t. v2
 - Remove forward declaration for wilc_enqueue_cmd
 - Change the interface 'wilc_mq_send' in a different patch
 - Avoid change in indentation in host_if_work and move it to
   a different patch

Cannot remove forward declaration of local function 'host_if_work'
   since there is a mutual dependency.

New changes in v4

Remove unused identifier 'hif_msg_q' which causes the build error.

Binoy

Binoy Jayan (3):
  staging: wilc1000: message_queue: Move code to host interface
  staging: wilc1000: Replace kthread with workqueue for host interface
  staging: wilc1000: Change interface wilc_mq_send to wilc_enqueue_cmd

 drivers/staging/wilc1000/Makefile |   1 -
 drivers/staging/wilc1000/TODO |   5 +
 drivers/staging/wilc1000/host_interface.c | 396 +++---
 drivers/staging/wilc1000/wilc_msgqueue.c  | 144 ---
 drivers/staging/wilc1000/wilc_msgqueue.h  |  28 ---
 5 files changed, 204 insertions(+), 370 deletions(-)
 delete mode 100644 drivers/staging/wilc1000/wilc_msgqueue.c
 delete mode 100644 drivers/staging/wilc1000/wilc_msgqueue.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v4] tools/perf: Fix the mask in regs_dump__printf and print_sample_iregs

2016-06-22 Thread Madhavan Srinivasan


On Thursday 23 June 2016 10:48 AM, Yury Norov wrote:
> On Thu, Jun 23, 2016 at 10:31:16AM +0530, Madhavan Srinivasan wrote:
>> When decoding the perf_regs mask in regs_dump__printf(),
>> we loop through the mask using find_first_bit and find_next_bit functions.
>> "mask" is of type "u64", but sent as a "unsigned long *" to
>> lib functions along with sizeof().
>>
>> While the exisitng code works fine in most of the case,
>> the logic is broken when using a 32bit perf on a 64bit kernel (Big Endian).
>> When reading u64 using (u32 *)()[0], perf (lib/find_*_bit()) assumes it 
>> gets
>> lower 32bits of u64 which is wrong. Proposed fix is to swap the words
>> of the u64 to handle this case. This is _not_ endianess swap.
>>
>> Suggested-by: Yury Norov 
>> Cc: Yury Norov 
>> Cc: Peter Zijlstra 
>> Cc: Ingo Molnar 
>> Cc: Arnaldo Carvalho de Melo 
>> Cc: Alexander Shishkin 
>> Cc: Jiri Olsa 
>> Cc: Adrian Hunter 
>> Cc: Kan Liang 
>> Cc: Wang Nan 
>> Cc: Michael Ellerman 
>> Signed-off-by: Madhavan Srinivasan 
>> ---
>> Changelog v3:
>> 1)Moved the swap function to lib/bitmap.c
>> 2)Added a macro for declaration
>> 3)Added the comments
>>
>> Changelog v2:
>> 1)Moved the swap code to a common function
>> 2)Added more comments in the code
>>
>> Changelog v1:
>> 1)updated commit message and patch subject
>> 2)Add the fix to print_sample_iregs() in builtin-script.c
>>
>>  tools/include/linux/bitmap.h |  5 +
>>  tools/lib/bitmap.c   | 18 ++
>>  tools/perf/builtin-script.c  |  4 +++-
>>  tools/perf/util/session.c|  4 +++-
>>  4 files changed, 29 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
>> index 28f5493da491..6be9a7ddcb03 100644
>> --- a/tools/include/linux/bitmap.h
>> +++ b/tools/include/linux/bitmap.h
>> @@ -2,14 +2,19 @@
>>  #define _PERF_BITOPS_H
>>  
>>  #include 
>> +#include 
>>  #include 
>>  
>>  #define DECLARE_BITMAP(name,bits) \
>>  unsigned long name[BITS_TO_LONGS(bits)]
>>  
>> +#define DECLARE_U64_BITMAP(__name) \
>> +unsigned long __name[sizeof(u64)/sizeof(unsigned long)]
>> +
>>  int __bitmap_weight(const unsigned long *bitmap, int bits);
>>  void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
>>   const unsigned long *bitmap2, int bits);
>> +void bitmap_from_u64(unsigned long *dst, u64 mask);
>>  
>>  #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 
>> 1)))
>>  
>> diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c
>> index 0a1adcfd..464a0cc63e6a 100644
>> --- a/tools/lib/bitmap.c
>> +++ b/tools/lib/bitmap.c
>> @@ -29,3 +29,21 @@ void __bitmap_or(unsigned long *dst, const unsigned long 
>> *bitmap1,
>>  for (k = 0; k < nr; k++)
>>  dst[k] = bitmap1[k] | bitmap2[k];
>>  }
>> +
>> +/*
>> + * bitmap_from_u64 - Check and swap words within u64.
>> + *  @mask: source bitmap
>> + *  @dst:  destination bitmap
>> + *
>> + * In 32 bit big endian userspace on a 64bit kernel, 'unsigned long' is 32 
>> bits.
>> + * When reading u64 using (u32 *)()[0] and (u32 *)()[1],
>> + * we will get wrong value for the mask. That is "(u32 *)()[0]"
>> + * gets upper 32 bits of u64, but perf may expect lower 32bits of u64.
>> + */
>> +void bitmap_from_u64(unsigned long *dst, u64 mask)
>> +{
>> +dst[0] = mask & ULONG_MAX;
>> +
>> +if (sizeof(mask) > sizeof(unsigned long))
>> +dst[1] = mask >> 32;
>> +}
>> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
>> index e3ce2f34d3ad..1120ca117071 100644
>> --- a/tools/perf/builtin-script.c
>> +++ b/tools/perf/builtin-script.c
>> @@ -412,11 +412,13 @@ static void print_sample_iregs(struct perf_sample 
>> *sample,
>>  struct regs_dump *regs = >intr_regs;
>>  uint64_t mask = attr->sample_regs_intr;
>>  unsigned i = 0, r;
>> +DECLARE_U64_BITMAP(_mask);
> I thought again, and realized that it may be just
>   DECLARE_BITMAP(_mask, 64);
>
> I think it's better than introduce new macro and I'd recommend you to
> send v5 doing this. But this version is OK to me as well. So it's up
> to you.

Yeah. Make sense. My bad did not look close at DECLARE_BITMAP.
Will send out a v5 now with that change.

Maddy
>
> Reviewed-by: Yury Norov 
>
>>  if (!regs)
>>  return;
>>  
>> -for_each_set_bit(r, (unsigned long *) , sizeof(mask) * 8) {
>> +bitmap_from_u64(_mask, mask);
>> +for_each_set_bit(r, _mask, sizeof(mask) * 8) {
>>  u64 val = regs->regs[i++];
>>  printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
>>  }
>> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
>> index 

Re: [PATCH v4] tools/perf: Fix the mask in regs_dump__printf and print_sample_iregs

2016-06-22 Thread Madhavan Srinivasan


On Thursday 23 June 2016 10:48 AM, Yury Norov wrote:
> On Thu, Jun 23, 2016 at 10:31:16AM +0530, Madhavan Srinivasan wrote:
>> When decoding the perf_regs mask in regs_dump__printf(),
>> we loop through the mask using find_first_bit and find_next_bit functions.
>> "mask" is of type "u64", but sent as a "unsigned long *" to
>> lib functions along with sizeof().
>>
>> While the exisitng code works fine in most of the case,
>> the logic is broken when using a 32bit perf on a 64bit kernel (Big Endian).
>> When reading u64 using (u32 *)()[0], perf (lib/find_*_bit()) assumes it 
>> gets
>> lower 32bits of u64 which is wrong. Proposed fix is to swap the words
>> of the u64 to handle this case. This is _not_ endianess swap.
>>
>> Suggested-by: Yury Norov 
>> Cc: Yury Norov 
>> Cc: Peter Zijlstra 
>> Cc: Ingo Molnar 
>> Cc: Arnaldo Carvalho de Melo 
>> Cc: Alexander Shishkin 
>> Cc: Jiri Olsa 
>> Cc: Adrian Hunter 
>> Cc: Kan Liang 
>> Cc: Wang Nan 
>> Cc: Michael Ellerman 
>> Signed-off-by: Madhavan Srinivasan 
>> ---
>> Changelog v3:
>> 1)Moved the swap function to lib/bitmap.c
>> 2)Added a macro for declaration
>> 3)Added the comments
>>
>> Changelog v2:
>> 1)Moved the swap code to a common function
>> 2)Added more comments in the code
>>
>> Changelog v1:
>> 1)updated commit message and patch subject
>> 2)Add the fix to print_sample_iregs() in builtin-script.c
>>
>>  tools/include/linux/bitmap.h |  5 +
>>  tools/lib/bitmap.c   | 18 ++
>>  tools/perf/builtin-script.c  |  4 +++-
>>  tools/perf/util/session.c|  4 +++-
>>  4 files changed, 29 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
>> index 28f5493da491..6be9a7ddcb03 100644
>> --- a/tools/include/linux/bitmap.h
>> +++ b/tools/include/linux/bitmap.h
>> @@ -2,14 +2,19 @@
>>  #define _PERF_BITOPS_H
>>  
>>  #include 
>> +#include 
>>  #include 
>>  
>>  #define DECLARE_BITMAP(name,bits) \
>>  unsigned long name[BITS_TO_LONGS(bits)]
>>  
>> +#define DECLARE_U64_BITMAP(__name) \
>> +unsigned long __name[sizeof(u64)/sizeof(unsigned long)]
>> +
>>  int __bitmap_weight(const unsigned long *bitmap, int bits);
>>  void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
>>   const unsigned long *bitmap2, int bits);
>> +void bitmap_from_u64(unsigned long *dst, u64 mask);
>>  
>>  #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 
>> 1)))
>>  
>> diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c
>> index 0a1adcfd..464a0cc63e6a 100644
>> --- a/tools/lib/bitmap.c
>> +++ b/tools/lib/bitmap.c
>> @@ -29,3 +29,21 @@ void __bitmap_or(unsigned long *dst, const unsigned long 
>> *bitmap1,
>>  for (k = 0; k < nr; k++)
>>  dst[k] = bitmap1[k] | bitmap2[k];
>>  }
>> +
>> +/*
>> + * bitmap_from_u64 - Check and swap words within u64.
>> + *  @mask: source bitmap
>> + *  @dst:  destination bitmap
>> + *
>> + * In 32 bit big endian userspace on a 64bit kernel, 'unsigned long' is 32 
>> bits.
>> + * When reading u64 using (u32 *)()[0] and (u32 *)()[1],
>> + * we will get wrong value for the mask. That is "(u32 *)()[0]"
>> + * gets upper 32 bits of u64, but perf may expect lower 32bits of u64.
>> + */
>> +void bitmap_from_u64(unsigned long *dst, u64 mask)
>> +{
>> +dst[0] = mask & ULONG_MAX;
>> +
>> +if (sizeof(mask) > sizeof(unsigned long))
>> +dst[1] = mask >> 32;
>> +}
>> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
>> index e3ce2f34d3ad..1120ca117071 100644
>> --- a/tools/perf/builtin-script.c
>> +++ b/tools/perf/builtin-script.c
>> @@ -412,11 +412,13 @@ static void print_sample_iregs(struct perf_sample 
>> *sample,
>>  struct regs_dump *regs = >intr_regs;
>>  uint64_t mask = attr->sample_regs_intr;
>>  unsigned i = 0, r;
>> +DECLARE_U64_BITMAP(_mask);
> I thought again, and realized that it may be just
>   DECLARE_BITMAP(_mask, 64);
>
> I think it's better than introduce new macro and I'd recommend you to
> send v5 doing this. But this version is OK to me as well. So it's up
> to you.

Yeah. Make sense. My bad did not look close at DECLARE_BITMAP.
Will send out a v5 now with that change.

Maddy
>
> Reviewed-by: Yury Norov 
>
>>  if (!regs)
>>  return;
>>  
>> -for_each_set_bit(r, (unsigned long *) , sizeof(mask) * 8) {
>> +bitmap_from_u64(_mask, mask);
>> +for_each_set_bit(r, _mask, sizeof(mask) * 8) {
>>  u64 val = regs->regs[i++];
>>  printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
>>  }
>> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
>> index 5214974e841a..fab1f9c1e0f5 100644
>> --- a/tools/perf/util/session.c
>> +++ b/tools/perf/util/session.c
>> @@ -940,8 +940,10 @@ static void branch_stack__printf(struct perf_sample 
>> *sample)
>>  static void regs_dump__printf(u64 mask, u64 *regs)
>>  {
>>  unsigned rid, i = 0;
>> +DECLARE_U64_BITMAP(_mask);
>>  
>> -  

[PATCH v10 03/10] perf record: Prepare picking perf_event_mmap_page from multiple evlists

2016-06-22 Thread Wang Nan
Following commits introduce new evlists to record. This patch adjusts
record__pick_pc() and introduces perf_evlist__pick_pc() to read control
page from one specific evlist. record__pick_pc() will be improved to search
control page from multiple evlists.

Signed-off-by: Wang Nan 
Cc: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/builtin-record.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index bc34e6b..10e6e89 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -685,10 +685,21 @@ perf_event__synth_time_conv(const struct 
perf_event_mmap_page *pc __maybe_unused
return 0;
 }
 
+static const struct perf_event_mmap_page *
+perf_evlist__pick_pc(struct perf_evlist *evlist)
+{
+   if (evlist && evlist->mmap && evlist->mmap[0].base)
+   return evlist->mmap[0].base;
+   return NULL;
+}
+
 static const struct perf_event_mmap_page *record__pick_pc(struct record *rec)
 {
-   if (rec->evlist && rec->evlist->mmap && rec->evlist->mmap[0].base)
-   return rec->evlist->mmap[0].base;
+   const struct perf_event_mmap_page *pc;
+
+   pc = perf_evlist__pick_pc(rec->evlist);
+   if (pc)
+   return pc;
return NULL;
 }
 
-- 
1.8.3.4



[PATCH v10 03/10] perf record: Prepare picking perf_event_mmap_page from multiple evlists

2016-06-22 Thread Wang Nan
Following commits introduce new evlists to record. This patch adjusts
record__pick_pc() and introduces perf_evlist__pick_pc() to read control
page from one specific evlist. record__pick_pc() will be improved to search
control page from multiple evlists.

Signed-off-by: Wang Nan 
Cc: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/builtin-record.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index bc34e6b..10e6e89 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -685,10 +685,21 @@ perf_event__synth_time_conv(const struct 
perf_event_mmap_page *pc __maybe_unused
return 0;
 }
 
+static const struct perf_event_mmap_page *
+perf_evlist__pick_pc(struct perf_evlist *evlist)
+{
+   if (evlist && evlist->mmap && evlist->mmap[0].base)
+   return evlist->mmap[0].base;
+   return NULL;
+}
+
 static const struct perf_event_mmap_page *record__pick_pc(struct record *rec)
 {
-   if (rec->evlist && rec->evlist->mmap && rec->evlist->mmap[0].base)
-   return rec->evlist->mmap[0].base;
+   const struct perf_event_mmap_page *pc;
+
+   pc = perf_evlist__pick_pc(rec->evlist);
+   if (pc)
+   return pc;
return NULL;
 }
 
-- 
1.8.3.4



[PATCH v10 05/10] perf tests: Add testcase for auxiliary evlist

2016-06-22 Thread Wang Nan
Improve test backward-ring-buffer, trace both enter and exit event of
prctl() syscall, utilize auxiliary evlist to mmap enter and exit event
into separated mmaps.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: He Kuang 
---
 tools/perf/tests/backward-ring-buffer.c | 90 ++---
 tools/perf/util/evlist.h|  8 +++
 2 files changed, 81 insertions(+), 17 deletions(-)

diff --git a/tools/perf/tests/backward-ring-buffer.c 
b/tools/perf/tests/backward-ring-buffer.c
index d9ba991..0b100b8 100644
--- a/tools/perf/tests/backward-ring-buffer.c
+++ b/tools/perf/tests/backward-ring-buffer.c
@@ -26,12 +26,21 @@ static void testcase(void)
 static int count_samples(struct perf_evlist *evlist, int *sample_count,
 int *comm_count)
 {
-   int i;
+   int i, dummy;
+
+   if (!comm_count)
+   comm_count = 
+   if (!sample_count)
+   sample_count = 
 
for (i = 0; i < evlist->nr_mmaps; i++) {
union perf_event *event;
 
-   perf_evlist__mmap_read_catchup(evlist, i);
+   /*
+* Before calling count_samples(), ring buffers in backward
+* evlist should have catched up with newest record
+* using perf_evlist__mmap_read_catchup_all().
+*/
while ((event = perf_evlist__mmap_read_backward(evlist, i)) != 
NULL) {
const u32 type = event->header.type;
 
@@ -51,34 +60,54 @@ static int count_samples(struct perf_evlist *evlist, int 
*sample_count,
return TEST_OK;
 }
 
-static int do_test(struct perf_evlist *evlist, int mmap_pages,
-  int *sample_count, int *comm_count)
+static int do_test(struct perf_evlist *evlist,
+  struct perf_evlist *aux_evlist,
+  int mmap_pages,
+  int *enter_sample_count,
+  int *exit_sample_count,
+  int *comm_count)
 {
int err;
char sbuf[STRERR_BUFSIZE];
 
-   err = perf_evlist__mmap(evlist, mmap_pages, true);
+   err = perf_evlist__mmap(evlist, mmap_pages, false);
if (err < 0) {
pr_debug("perf_evlist__mmap: %s\n",
 strerror_r(errno, sbuf, sizeof(sbuf)));
return TEST_FAIL;
}
 
+   err = perf_evlist__mmap(aux_evlist, mmap_pages, true);
+   if (err < 0) {
+   pr_debug("perf_evlist__mmap for aux_evlist: %s\n",
+strerror_r(errno, sbuf, sizeof(sbuf)));
+   return TEST_FAIL;
+   }
+
perf_evlist__enable(evlist);
testcase();
perf_evlist__disable(evlist);
 
-   err = count_samples(evlist, sample_count, comm_count);
+   perf_evlist__mmap_read_catchup_all(aux_evlist);
+   err = count_samples(aux_evlist, exit_sample_count, comm_count);
+   if (err)
+   goto errout;
+   err = count_samples(evlist, enter_sample_count, NULL);
+   if (err)
+   goto errout;
+errout:
perf_evlist__munmap(evlist);
+   perf_evlist__munmap(aux_evlist);
return err;
 }
 
 
 int test__backward_ring_buffer(int subtest __maybe_unused)
 {
-   int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0;
+   int ret = TEST_SKIP, err;
+   int enter_sample_count = 0, exit_sample_count = 0, comm_count = 0;
char pid[16], sbuf[STRERR_BUFSIZE];
-   struct perf_evlist *evlist;
+   struct perf_evlist *evlist, *aux_evlist = NULL;
struct perf_evsel *evsel __maybe_unused;
struct parse_events_error parse_error;
struct record_opts opts = {
@@ -115,11 +144,22 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
goto out_delete_evlist;
}
 
-   perf_evlist__config(evlist, , NULL);
+   /*
+* Set backward bit, ring buffer should be writing from end. Record
+* it in aux evlist
+*/
+   perf_evlist__last(evlist)->overwrite = true;
+   perf_evlist__last(evlist)->attr.write_backward = 1;
 
-   /* Set backward bit, ring buffer should be writing from end */
-   evlist__for_each(evlist, evsel)
-   evsel->attr.write_backward = 1;
+   err = parse_events(evlist, "syscalls:sys_exit_prctl", _error);
+   if (err) {
+   pr_debug("Failed to parse tracepoint event, try use root\n");
+   ret = TEST_SKIP;
+   goto out_delete_evlist;
+   }
+   /* Don't set backward bit for exit event. Record it in main evlist */
+
+   perf_evlist__config(evlist, , NULL);
 
err = perf_evlist__open(evlist);
if (err < 0) {
@@ -128,24 +168,40 @@ int test__backward_ring_buffer(int subtest 

[PATCH v10 01/10] perf record: Prepare mmap multiple evlists

2016-06-22 Thread Wang Nan
Following commits introduce multiple evlists to record. This patch
extracts perf_evlist__mmap_ex() processing to a new function, creates
record__mmap() and record__mmap_evlist() to wrap perf_evlist__mmap_ex()
and its error processing. They will be improvemented to create mmap
for all evlists.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: He Kuang 
---
 tools/perf/builtin-record.c | 56 +
 1 file changed, 36 insertions(+), 20 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index b1304eb..7998ec3 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -341,6 +341,40 @@ int auxtrace_record__snapshot_start(struct auxtrace_record 
*itr __maybe_unused)
 
 #endif
 
+static int record__mmap_evlist(struct record *rec,
+  struct perf_evlist *evlist)
+{
+   struct record_opts *opts = >opts;
+   char msg[512];
+
+   if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
+opts->auxtrace_mmap_pages,
+opts->auxtrace_snapshot_mode) < 0) {
+   if (errno == EPERM) {
+   pr_err("Permission error mapping pages.\n"
+  "Consider increasing "
+  "/proc/sys/kernel/perf_event_mlock_kb,\n"
+  "or try again with a smaller value of 
-m/--mmap_pages.\n"
+  "(current value: %u,%u)\n",
+  opts->mmap_pages, opts->auxtrace_mmap_pages);
+   return -errno;
+   } else {
+   pr_err("failed to mmap with %d (%s)\n", errno,
+   strerror_r(errno, msg, sizeof(msg)));
+   if (errno)
+   return -errno;
+   else
+   return -EINVAL;
+   }
+   }
+   return 0;
+}
+
+static int record__mmap(struct record *rec)
+{
+   return record__mmap_evlist(rec, rec->evlist);
+}
+
 static int record__open(struct record *rec)
 {
char msg[512];
@@ -377,27 +411,9 @@ try_again:
goto out;
}
 
-   if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
-opts->auxtrace_mmap_pages,
-opts->auxtrace_snapshot_mode) < 0) {
-   if (errno == EPERM) {
-   pr_err("Permission error mapping pages.\n"
-  "Consider increasing "
-  "/proc/sys/kernel/perf_event_mlock_kb,\n"
-  "or try again with a smaller value of 
-m/--mmap_pages.\n"
-  "(current value: %u,%u)\n",
-  opts->mmap_pages, opts->auxtrace_mmap_pages);
-   rc = -errno;
-   } else {
-   pr_err("failed to mmap with %d (%s)\n", errno,
-   strerror_r(errno, msg, sizeof(msg)));
-   if (errno)
-   rc = -errno;
-   else
-   rc = -EINVAL;
-   }
+   rc = record__mmap(rec);
+   if (rc)
goto out;
-   }
 
session->evlist = evlist;
perf_session__set_id_hdr_size(session);
-- 
1.8.3.4



[PATCH v10 01/10] perf record: Prepare mmap multiple evlists

2016-06-22 Thread Wang Nan
Following commits introduce multiple evlists to record. This patch
extracts perf_evlist__mmap_ex() processing to a new function, creates
record__mmap() and record__mmap_evlist() to wrap perf_evlist__mmap_ex()
and its error processing. They will be improvemented to create mmap
for all evlists.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: He Kuang 
---
 tools/perf/builtin-record.c | 56 +
 1 file changed, 36 insertions(+), 20 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index b1304eb..7998ec3 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -341,6 +341,40 @@ int auxtrace_record__snapshot_start(struct auxtrace_record 
*itr __maybe_unused)
 
 #endif
 
+static int record__mmap_evlist(struct record *rec,
+  struct perf_evlist *evlist)
+{
+   struct record_opts *opts = >opts;
+   char msg[512];
+
+   if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
+opts->auxtrace_mmap_pages,
+opts->auxtrace_snapshot_mode) < 0) {
+   if (errno == EPERM) {
+   pr_err("Permission error mapping pages.\n"
+  "Consider increasing "
+  "/proc/sys/kernel/perf_event_mlock_kb,\n"
+  "or try again with a smaller value of 
-m/--mmap_pages.\n"
+  "(current value: %u,%u)\n",
+  opts->mmap_pages, opts->auxtrace_mmap_pages);
+   return -errno;
+   } else {
+   pr_err("failed to mmap with %d (%s)\n", errno,
+   strerror_r(errno, msg, sizeof(msg)));
+   if (errno)
+   return -errno;
+   else
+   return -EINVAL;
+   }
+   }
+   return 0;
+}
+
+static int record__mmap(struct record *rec)
+{
+   return record__mmap_evlist(rec, rec->evlist);
+}
+
 static int record__open(struct record *rec)
 {
char msg[512];
@@ -377,27 +411,9 @@ try_again:
goto out;
}
 
-   if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
-opts->auxtrace_mmap_pages,
-opts->auxtrace_snapshot_mode) < 0) {
-   if (errno == EPERM) {
-   pr_err("Permission error mapping pages.\n"
-  "Consider increasing "
-  "/proc/sys/kernel/perf_event_mlock_kb,\n"
-  "or try again with a smaller value of 
-m/--mmap_pages.\n"
-  "(current value: %u,%u)\n",
-  opts->mmap_pages, opts->auxtrace_mmap_pages);
-   rc = -errno;
-   } else {
-   pr_err("failed to mmap with %d (%s)\n", errno,
-   strerror_r(errno, msg, sizeof(msg)));
-   if (errno)
-   rc = -errno;
-   else
-   rc = -EINVAL;
-   }
+   rc = record__mmap(rec);
+   if (rc)
goto out;
-   }
 
session->evlist = evlist;
perf_session__set_id_hdr_size(session);
-- 
1.8.3.4



[PATCH v10 05/10] perf tests: Add testcase for auxiliary evlist

2016-06-22 Thread Wang Nan
Improve test backward-ring-buffer, trace both enter and exit event of
prctl() syscall, utilize auxiliary evlist to mmap enter and exit event
into separated mmaps.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: He Kuang 
---
 tools/perf/tests/backward-ring-buffer.c | 90 ++---
 tools/perf/util/evlist.h|  8 +++
 2 files changed, 81 insertions(+), 17 deletions(-)

diff --git a/tools/perf/tests/backward-ring-buffer.c 
b/tools/perf/tests/backward-ring-buffer.c
index d9ba991..0b100b8 100644
--- a/tools/perf/tests/backward-ring-buffer.c
+++ b/tools/perf/tests/backward-ring-buffer.c
@@ -26,12 +26,21 @@ static void testcase(void)
 static int count_samples(struct perf_evlist *evlist, int *sample_count,
 int *comm_count)
 {
-   int i;
+   int i, dummy;
+
+   if (!comm_count)
+   comm_count = 
+   if (!sample_count)
+   sample_count = 
 
for (i = 0; i < evlist->nr_mmaps; i++) {
union perf_event *event;
 
-   perf_evlist__mmap_read_catchup(evlist, i);
+   /*
+* Before calling count_samples(), ring buffers in backward
+* evlist should have catched up with newest record
+* using perf_evlist__mmap_read_catchup_all().
+*/
while ((event = perf_evlist__mmap_read_backward(evlist, i)) != 
NULL) {
const u32 type = event->header.type;
 
@@ -51,34 +60,54 @@ static int count_samples(struct perf_evlist *evlist, int 
*sample_count,
return TEST_OK;
 }
 
-static int do_test(struct perf_evlist *evlist, int mmap_pages,
-  int *sample_count, int *comm_count)
+static int do_test(struct perf_evlist *evlist,
+  struct perf_evlist *aux_evlist,
+  int mmap_pages,
+  int *enter_sample_count,
+  int *exit_sample_count,
+  int *comm_count)
 {
int err;
char sbuf[STRERR_BUFSIZE];
 
-   err = perf_evlist__mmap(evlist, mmap_pages, true);
+   err = perf_evlist__mmap(evlist, mmap_pages, false);
if (err < 0) {
pr_debug("perf_evlist__mmap: %s\n",
 strerror_r(errno, sbuf, sizeof(sbuf)));
return TEST_FAIL;
}
 
+   err = perf_evlist__mmap(aux_evlist, mmap_pages, true);
+   if (err < 0) {
+   pr_debug("perf_evlist__mmap for aux_evlist: %s\n",
+strerror_r(errno, sbuf, sizeof(sbuf)));
+   return TEST_FAIL;
+   }
+
perf_evlist__enable(evlist);
testcase();
perf_evlist__disable(evlist);
 
-   err = count_samples(evlist, sample_count, comm_count);
+   perf_evlist__mmap_read_catchup_all(aux_evlist);
+   err = count_samples(aux_evlist, exit_sample_count, comm_count);
+   if (err)
+   goto errout;
+   err = count_samples(evlist, enter_sample_count, NULL);
+   if (err)
+   goto errout;
+errout:
perf_evlist__munmap(evlist);
+   perf_evlist__munmap(aux_evlist);
return err;
 }
 
 
 int test__backward_ring_buffer(int subtest __maybe_unused)
 {
-   int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0;
+   int ret = TEST_SKIP, err;
+   int enter_sample_count = 0, exit_sample_count = 0, comm_count = 0;
char pid[16], sbuf[STRERR_BUFSIZE];
-   struct perf_evlist *evlist;
+   struct perf_evlist *evlist, *aux_evlist = NULL;
struct perf_evsel *evsel __maybe_unused;
struct parse_events_error parse_error;
struct record_opts opts = {
@@ -115,11 +144,22 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
goto out_delete_evlist;
}
 
-   perf_evlist__config(evlist, , NULL);
+   /*
+* Set backward bit, ring buffer should be writing from end. Record
+* it in aux evlist
+*/
+   perf_evlist__last(evlist)->overwrite = true;
+   perf_evlist__last(evlist)->attr.write_backward = 1;
 
-   /* Set backward bit, ring buffer should be writing from end */
-   evlist__for_each(evlist, evsel)
-   evsel->attr.write_backward = 1;
+   err = parse_events(evlist, "syscalls:sys_exit_prctl", _error);
+   if (err) {
+   pr_debug("Failed to parse tracepoint event, try use root\n");
+   ret = TEST_SKIP;
+   goto out_delete_evlist;
+   }
+   /* Don't set backward bit for exit event. Record it in main evlist */
+
+   perf_evlist__config(evlist, , NULL);
 
err = perf_evlist__open(evlist);
if (err < 0) {
@@ -128,24 +168,40 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
goto out_delete_evlist;
}
 
+   aux_evlist = perf_evlist__new_aux(evlist);
+   if (!aux_evlist) {
+  

[PATCH v10 06/10] perf record: Introduce rec->overwrite_evlist for overwritable events

2016-06-22 Thread Wang Nan
Create an auxiliary evlist for overwritable events.

Before mmap, build this evlist and set 'overwrite' and 'backward'
attribute. Since perf_evlist__mmap_ex() only maps events when
evsel->overwrite matches evlist's corresponding attributes, with
these two evlists an event goes to either rec->evlist or
rec->overwrite_evlist.

Signed-off-by: Wang Nan 
Cc: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/builtin-record.c | 59 ++---
 1 file changed, 56 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 10e6e89..d1873ee 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -50,6 +50,7 @@ struct record {
struct perf_data_file   file;
struct auxtrace_record  *itr;
struct perf_evlist  *evlist;
+   struct perf_evlist  *overwrite_evlist;
struct perf_session *session;
const char  *progname;
int realtime_prio;
@@ -341,13 +342,41 @@ int auxtrace_record__snapshot_start(struct 
auxtrace_record *itr __maybe_unused)
 
 #endif
 
+static int record__create_overwrite_evlist(struct record *rec)
+{
+   struct perf_evlist *evlist = rec->evlist;
+   struct perf_evsel *pos;
+
+   evlist__for_each(evlist, pos) {
+   if (!pos->overwrite)
+   continue;
+
+   if (!rec->overwrite_evlist) {
+   rec->overwrite_evlist = perf_evlist__new_aux(evlist);
+   if (rec->overwrite_evlist) {
+   rec->overwrite_evlist->backward = true;
+   rec->overwrite_evlist->overwrite = true;
+   return 0;
+   } else
+   return -ENOMEM;
+   }
+   }
+   return 0;
+}
+
 static int record__mmap_evlist(struct record *rec,
-  struct perf_evlist *evlist)
+  struct perf_evlist *evlist,
+  bool overwrite)
 {
struct record_opts *opts = >opts;
char msg[512];
 
-   if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
+   /*
+* Don't use evlist->overwrite because it is logically an
+* internal attribute and is set by perf_evlist__mmap_ex().
+* Avoid circular dependency.
+*/
+   if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, overwrite,
 opts->auxtrace_mmap_pages,
 opts->auxtrace_snapshot_mode) < 0) {
if (errno == EPERM) {
@@ -372,7 +401,23 @@ static int record__mmap_evlist(struct record *rec,
 
 static int record__mmap(struct record *rec)
 {
-   return record__mmap_evlist(rec, rec->evlist);
+   int err;
+
+   err = record__create_overwrite_evlist(rec);
+   if (err)
+   return err;
+
+   err = record__mmap_evlist(rec, rec->evlist, false);
+   if (err)
+   return err;
+
+   if (!rec->overwrite_evlist)
+   return 0;
+
+   err = record__mmap_evlist(rec, rec->overwrite_evlist, true);
+   if (err)
+   return err;
+   return 0;
 }
 
 static int record__open(struct record *rec)
@@ -697,9 +742,14 @@ static const struct perf_event_mmap_page 
*record__pick_pc(struct record *rec)
 {
const struct perf_event_mmap_page *pc;
 
+   /* Change it to a loop if a new aux evlist is added */
pc = perf_evlist__pick_pc(rec->evlist);
if (pc)
return pc;
+   pc = perf_evlist__pick_pc(rec->overwrite_evlist);
+   if (pc)
+   return pc;
+
return NULL;
 }
 
@@ -1310,6 +1360,7 @@ static struct record record = {
.mmap2  = perf_event__process_mmap2,
.ordered_events = true,
},
+   .overwrite_evlist = NULL,
 };
 
 const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
@@ -1613,6 +1664,8 @@ int cmd_record(int argc, const char **argv, const char 
*prefix __maybe_unused)
err = __cmd_record(, argc, argv);
 out_symbol_exit:
perf_evlist__delete(rec->evlist);
+   if (rec->overwrite_evlist)
+   perf_evlist__delete(rec->overwrite_evlist);
symbol__exit();
auxtrace_record__free(rec->itr);
return err;
-- 
1.8.3.4



[PATCH v10 06/10] perf record: Introduce rec->overwrite_evlist for overwritable events

2016-06-22 Thread Wang Nan
Create an auxiliary evlist for overwritable events.

Before mmap, build this evlist and set 'overwrite' and 'backward'
attribute. Since perf_evlist__mmap_ex() only maps events when
evsel->overwrite matches evlist's corresponding attributes, with
these two evlists an event goes to either rec->evlist or
rec->overwrite_evlist.

Signed-off-by: Wang Nan 
Cc: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/builtin-record.c | 59 ++---
 1 file changed, 56 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 10e6e89..d1873ee 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -50,6 +50,7 @@ struct record {
struct perf_data_file   file;
struct auxtrace_record  *itr;
struct perf_evlist  *evlist;
+   struct perf_evlist  *overwrite_evlist;
struct perf_session *session;
const char  *progname;
int realtime_prio;
@@ -341,13 +342,41 @@ int auxtrace_record__snapshot_start(struct 
auxtrace_record *itr __maybe_unused)
 
 #endif
 
+static int record__create_overwrite_evlist(struct record *rec)
+{
+   struct perf_evlist *evlist = rec->evlist;
+   struct perf_evsel *pos;
+
+   evlist__for_each(evlist, pos) {
+   if (!pos->overwrite)
+   continue;
+
+   if (!rec->overwrite_evlist) {
+   rec->overwrite_evlist = perf_evlist__new_aux(evlist);
+   if (rec->overwrite_evlist) {
+   rec->overwrite_evlist->backward = true;
+   rec->overwrite_evlist->overwrite = true;
+   return 0;
+   } else
+   return -ENOMEM;
+   }
+   }
+   return 0;
+}
+
 static int record__mmap_evlist(struct record *rec,
-  struct perf_evlist *evlist)
+  struct perf_evlist *evlist,
+  bool overwrite)
 {
struct record_opts *opts = >opts;
char msg[512];
 
-   if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
+   /*
+* Don't use evlist->overwrite because it is logically an
+* internal attribute and is set by perf_evlist__mmap_ex().
+* Avoid circular dependency.
+*/
+   if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, overwrite,
 opts->auxtrace_mmap_pages,
 opts->auxtrace_snapshot_mode) < 0) {
if (errno == EPERM) {
@@ -372,7 +401,23 @@ static int record__mmap_evlist(struct record *rec,
 
 static int record__mmap(struct record *rec)
 {
-   return record__mmap_evlist(rec, rec->evlist);
+   int err;
+
+   err = record__create_overwrite_evlist(rec);
+   if (err)
+   return err;
+
+   err = record__mmap_evlist(rec, rec->evlist, false);
+   if (err)
+   return err;
+
+   if (!rec->overwrite_evlist)
+   return 0;
+
+   err = record__mmap_evlist(rec, rec->overwrite_evlist, true);
+   if (err)
+   return err;
+   return 0;
 }
 
 static int record__open(struct record *rec)
@@ -697,9 +742,14 @@ static const struct perf_event_mmap_page 
*record__pick_pc(struct record *rec)
 {
const struct perf_event_mmap_page *pc;
 
+   /* Change it to a loop if a new aux evlist is added */
pc = perf_evlist__pick_pc(rec->evlist);
if (pc)
return pc;
+   pc = perf_evlist__pick_pc(rec->overwrite_evlist);
+   if (pc)
+   return pc;
+
return NULL;
 }
 
@@ -1310,6 +1360,7 @@ static struct record record = {
.mmap2  = perf_event__process_mmap2,
.ordered_events = true,
},
+   .overwrite_evlist = NULL,
 };
 
 const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
@@ -1613,6 +1664,8 @@ int cmd_record(int argc, const char **argv, const char 
*prefix __maybe_unused)
err = __cmd_record(, argc, argv);
 out_symbol_exit:
perf_evlist__delete(rec->evlist);
+   if (rec->overwrite_evlist)
+   perf_evlist__delete(rec->overwrite_evlist);
symbol__exit();
auxtrace_record__free(rec->itr);
return err;
-- 
1.8.3.4



Re: [PATCH 1/6] regulator: core: Allow simultaneous use of enable op and GPIO

2016-06-22 Thread Alexandre Courbot
On Thu, Jun 23, 2016 at 10:10 AM, Alexandre Courbot  wrote:
> On Wed, Jun 22, 2016 at 7:34 PM, Mark Brown  wrote:
>> On Wed, Jun 22, 2016 at 05:25:53PM +0900, Alexandre Courbot wrote:
>>> The current regulator enable/disable mechanism does not call the driver
>>> enable/disable op if an enable GPIO is set. It may be desirable to use
>>> both mechanisms though, e.g. in the case of a PWM regulator that also
>>> has an enable GPIO.
>>>
>>> _regulator_is_enabled() is also updated in order to take both enable
>>> conditions into account.
>>
>> This is going to break or at least reduce the performance of a lot of
>> users - it is very common for regulators to have configurable support
>> for a GPIO enable in addition to a register enable with the GPIO enable
>> replacing a register enable for improved performance.
>
> Ah, I wasn't aware of this.
>
>> If you have some
>> strange device that requires GPIO and other operations the driver should
>> handle that, if nothing else it's likely that there are sequencing
>> requirements between the two which we are probably not going to get
>> right for everyone in the core.
>
> Having dedicated enable GPIO code in the PWM driver sounded redundant
> since we already have the same in the core, which is why I went for
> this approach. But with your above point it seems like I have no
> choice.

There is also another potential problem with not using the enable GPIO
in the regulator core: said GPIO can not be shared anymore between
several regulators, as this was handled by the core.

That's not a big issue for our use-case but I just wanted to point it
out. Maybe we need a more global solution for shared GPIOs, but I can
see a few challenges on the way (e.g. which policy to adopt and how to
handle conflicts).


[PATCH v10 02/10] perf record: Prepare reading from multiple evlists in record__mmap_read_all()

2016-06-22 Thread Wang Nan
Following commits introduce new evlists to record. This patch adjusts
record__mmap_read_all() and record__mmap_read(): converting original
record__mmap_read_all() to record__mmap_read_evlist(), read from one
evlist; makes record__mmap_read() reading from specific evlist.
record__mmap_read_all() will be improved to read from multiple evlists.

Signed-off-by: Wang Nan 
Cc: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/builtin-record.c | 34 --
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 7998ec3..bc34e6b 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -131,9 +131,9 @@ rb_find_range(struct perf_evlist *evlist,
return backward_rb_find_range(data, mask, head, start, end);
 }
 
-static int record__mmap_read(struct record *rec, int idx)
+static int record__mmap_read(struct record *rec, struct perf_evlist *evlist, 
int idx)
 {
-   struct perf_mmap *md = >evlist->mmap[idx];
+   struct perf_mmap *md = >mmap[idx];
u64 head = perf_mmap__read_head(md);
u64 old = md->prev;
u64 end = head, start = old;
@@ -142,7 +142,7 @@ static int record__mmap_read(struct record *rec, int idx)
void *buf;
int rc = 0;
 
-   if (rb_find_range(rec->evlist, data, md->mask, head,
+   if (rb_find_range(evlist, data, md->mask, head,
  old, , ))
return -1;
 
@@ -156,7 +156,7 @@ static int record__mmap_read(struct record *rec, int idx)
WARN_ONCE(1, "failed to keep up with mmap data. (warn only 
once)\n");
 
md->prev = head;
-   perf_evlist__mmap_consume(rec->evlist, idx);
+   perf_evlist__mmap_consume(evlist, idx);
return 0;
}
 
@@ -181,7 +181,7 @@ static int record__mmap_read(struct record *rec, int idx)
}
 
md->prev = head;
-   perf_evlist__mmap_consume(rec->evlist, idx);
+   perf_evlist__mmap_consume(evlist, idx);
 out:
return rc;
 }
@@ -497,17 +497,20 @@ static struct perf_event_header finished_round_event = {
.type = PERF_RECORD_FINISHED_ROUND,
 };
 
-static int record__mmap_read_all(struct record *rec)
+static int record__mmap_read_evlist(struct record *rec, struct perf_evlist 
*evlist)
 {
u64 bytes_written = rec->bytes_written;
int i;
int rc = 0;
 
-   for (i = 0; i < rec->evlist->nr_mmaps; i++) {
-   struct auxtrace_mmap *mm = >evlist->mmap[i].auxtrace_mmap;
+   if (!evlist)
+   return 0;
+
+   for (i = 0; i < evlist->nr_mmaps; i++) {
+   struct auxtrace_mmap *mm = >mmap[i].auxtrace_mmap;
 
-   if (rec->evlist->mmap[i].base) {
-   if (record__mmap_read(rec, i) != 0) {
+   if (evlist->mmap[i].base) {
+   if (record__mmap_read(rec, evlist, i) != 0) {
rc = -1;
goto out;
}
@@ -531,6 +534,17 @@ out:
return rc;
 }
 
+static int record__mmap_read_all(struct record *rec)
+{
+   int err;
+
+   err = record__mmap_read_evlist(rec, rec->evlist);
+   if (err)
+   return err;
+
+   return err;
+}
+
 static void record__init_features(struct record *rec)
 {
struct perf_session *session = rec->session;
-- 
1.8.3.4



[PATCH v10 10/10] perf tools: Add --tail-synthesize option

2016-06-22 Thread Wang Nan
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts, non-sample
events may lost, which makes following 'perf report' unable to identify
proc name and mmap layout. For example:

 # perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null

send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:

 # perf script -i perf.data.2016061522374354
 perf 24478 [004] 2581325.601789:  raw_syscalls:sys_exit: NR 0 = 512
 
 Should be 'dd'
   27b2e8 syscall_slow_exit_work+0xfe2000e3 
(/lib/modules/4.6.0-rc3+/build/vmlinux)
   203cc7 do_syscall_64+0xfe200117 
(/lib/modules/4.6.0-rc3+/build/vmlinux)
   b18d83 return_from_SYSCALL_64+0xfe20 
(/lib/modules/4.6.0-rc3+/build/vmlinux)
 7f47c417edf0 [unknown] ([unknown])
 
 Fail to unwind

This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.

After this patch:
 # perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output 
--tail-synthesize \
dd if=/dev/zero of=/dev/null

 # perf script -i perf.data.2016061600544998
 dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
 ^^
 Correct comm
   203a18 syscall_trace_enter_phase2+0xfe2001a8 
([kernel.kallsyms])
   203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
   203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
   b18d83 return_from_SYSCALL_64+0xfe20 ([kernel.kallsyms])
d8e50 __GI___libc_write+0x01d9639f4010 
(/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^
Correct unwind

This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its
'/proc//mmap' becomes empty. However, this is a cheaper choice. To
completely solve this problem we need to continously output non-sample
events. To satisify the requirement of daemonization, we need to merge
them periodically. It is possible but requires much more code and cycles.

Automatically select --tail-synthesize when --overwrite is provided.

Signed-off-by: Wang Nan 
Cc: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/Documentation/perf-record.txt |  8 
 tools/perf/builtin-record.c  | 31 +--
 tools/perf/perf.h|  1 +
 3 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt 
b/tools/perf/Documentation/perf-record.txt
index 384c630..69966ab 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -367,6 +367,12 @@ options.
 'perf record --dry-run -e' can act as a BPF script compiler if llvm.dump-obj
 in config file is set to true.
 
+--tail-synthesize::
+Instead of collecting non-sample events (for example, fork, comm, mmap) at
+the beginning of record, collect them during finalizing an output file.
+The collected non-sample events reflects the status of the system when
+record is finished.
+
 --overwrite::
 Makes all events use an overwritable ring buffer. An overwritable ring
 buffer works like a flight recorder: when it gets full, the kernel will
@@ -381,6 +387,8 @@ those fitting in the ring buffer at that moment.
 'overwrite' attribute can also be set or canceled for an event using
 config terms. For example: 'cycles/overwrite/' and 
'instructions/no-overwrite/'.
 
+Implies --tail-synthesize.
+
 SEE ALSO
 
 linkperf:perf-stat[1], linkperf:perf-list[1]
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 4a265e7..19bef09 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -741,13 +741,16 @@ record__finish_output(struct record *rec)
return;
 }
 
-static int record__synthesize_workload(struct record *rec)
+static int record__synthesize_workload(struct record *rec, bool tail)
 {
struct {
struct thread_map map;
struct thread_map_data map_data;
} thread_map;
 
+   if (rec->opts.tail_synthesize != tail)
+   return 0;
+
thread_map.map.nr = 1;
thread_map.map.map[0].pid = rec->evlist->workload.pid;

Re: [PATCH 1/6] regulator: core: Allow simultaneous use of enable op and GPIO

2016-06-22 Thread Alexandre Courbot
On Thu, Jun 23, 2016 at 10:10 AM, Alexandre Courbot  wrote:
> On Wed, Jun 22, 2016 at 7:34 PM, Mark Brown  wrote:
>> On Wed, Jun 22, 2016 at 05:25:53PM +0900, Alexandre Courbot wrote:
>>> The current regulator enable/disable mechanism does not call the driver
>>> enable/disable op if an enable GPIO is set. It may be desirable to use
>>> both mechanisms though, e.g. in the case of a PWM regulator that also
>>> has an enable GPIO.
>>>
>>> _regulator_is_enabled() is also updated in order to take both enable
>>> conditions into account.
>>
>> This is going to break or at least reduce the performance of a lot of
>> users - it is very common for regulators to have configurable support
>> for a GPIO enable in addition to a register enable with the GPIO enable
>> replacing a register enable for improved performance.
>
> Ah, I wasn't aware of this.
>
>> If you have some
>> strange device that requires GPIO and other operations the driver should
>> handle that, if nothing else it's likely that there are sequencing
>> requirements between the two which we are probably not going to get
>> right for everyone in the core.
>
> Having dedicated enable GPIO code in the PWM driver sounded redundant
> since we already have the same in the core, which is why I went for
> this approach. But with your above point it seems like I have no
> choice.

There is also another potential problem with not using the enable GPIO
in the regulator core: said GPIO can not be shared anymore between
several regulators, as this was handled by the core.

That's not a big issue for our use-case but I just wanted to point it
out. Maybe we need a more global solution for shared GPIOs, but I can
see a few challenges on the way (e.g. which policy to adopt and how to
handle conflicts).


[PATCH v10 02/10] perf record: Prepare reading from multiple evlists in record__mmap_read_all()

2016-06-22 Thread Wang Nan
Following commits introduce new evlists to record. This patch adjusts
record__mmap_read_all() and record__mmap_read(): converting original
record__mmap_read_all() to record__mmap_read_evlist(), read from one
evlist; makes record__mmap_read() reading from specific evlist.
record__mmap_read_all() will be improved to read from multiple evlists.

Signed-off-by: Wang Nan 
Cc: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/builtin-record.c | 34 --
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 7998ec3..bc34e6b 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -131,9 +131,9 @@ rb_find_range(struct perf_evlist *evlist,
return backward_rb_find_range(data, mask, head, start, end);
 }
 
-static int record__mmap_read(struct record *rec, int idx)
+static int record__mmap_read(struct record *rec, struct perf_evlist *evlist, 
int idx)
 {
-   struct perf_mmap *md = >evlist->mmap[idx];
+   struct perf_mmap *md = >mmap[idx];
u64 head = perf_mmap__read_head(md);
u64 old = md->prev;
u64 end = head, start = old;
@@ -142,7 +142,7 @@ static int record__mmap_read(struct record *rec, int idx)
void *buf;
int rc = 0;
 
-   if (rb_find_range(rec->evlist, data, md->mask, head,
+   if (rb_find_range(evlist, data, md->mask, head,
  old, , ))
return -1;
 
@@ -156,7 +156,7 @@ static int record__mmap_read(struct record *rec, int idx)
WARN_ONCE(1, "failed to keep up with mmap data. (warn only 
once)\n");
 
md->prev = head;
-   perf_evlist__mmap_consume(rec->evlist, idx);
+   perf_evlist__mmap_consume(evlist, idx);
return 0;
}
 
@@ -181,7 +181,7 @@ static int record__mmap_read(struct record *rec, int idx)
}
 
md->prev = head;
-   perf_evlist__mmap_consume(rec->evlist, idx);
+   perf_evlist__mmap_consume(evlist, idx);
 out:
return rc;
 }
@@ -497,17 +497,20 @@ static struct perf_event_header finished_round_event = {
.type = PERF_RECORD_FINISHED_ROUND,
 };
 
-static int record__mmap_read_all(struct record *rec)
+static int record__mmap_read_evlist(struct record *rec, struct perf_evlist 
*evlist)
 {
u64 bytes_written = rec->bytes_written;
int i;
int rc = 0;
 
-   for (i = 0; i < rec->evlist->nr_mmaps; i++) {
-   struct auxtrace_mmap *mm = >evlist->mmap[i].auxtrace_mmap;
+   if (!evlist)
+   return 0;
+
+   for (i = 0; i < evlist->nr_mmaps; i++) {
+   struct auxtrace_mmap *mm = >mmap[i].auxtrace_mmap;
 
-   if (rec->evlist->mmap[i].base) {
-   if (record__mmap_read(rec, i) != 0) {
+   if (evlist->mmap[i].base) {
+   if (record__mmap_read(rec, evlist, i) != 0) {
rc = -1;
goto out;
}
@@ -531,6 +534,17 @@ out:
return rc;
 }
 
+static int record__mmap_read_all(struct record *rec)
+{
+   int err;
+
+   err = record__mmap_read_evlist(rec, rec->evlist);
+   if (err)
+   return err;
+
+   return err;
+}
+
 static void record__init_features(struct record *rec)
 {
struct perf_session *session = rec->session;
-- 
1.8.3.4



[PATCH v10 10/10] perf tools: Add --tail-synthesize option

2016-06-22 Thread Wang Nan
When working with overwritable ring buffer there's a inconvenience
problem: if perf dumps data after a long period after it starts, non-sample
events may lost, which makes following 'perf report' unable to identify
proc name and mmap layout. For example:

 # perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output \
dd if=/dev/zero of=/dev/null

send SIGUSR2 after dd runs long enough. The resuling perf.data lost
correct comm and mmap events:

 # perf script -i perf.data.2016061522374354
 perf 24478 [004] 2581325.601789:  raw_syscalls:sys_exit: NR 0 = 512
 
 Should be 'dd'
   27b2e8 syscall_slow_exit_work+0xfe2000e3 
(/lib/modules/4.6.0-rc3+/build/vmlinux)
   203cc7 do_syscall_64+0xfe200117 
(/lib/modules/4.6.0-rc3+/build/vmlinux)
   b18d83 return_from_SYSCALL_64+0xfe20 
(/lib/modules/4.6.0-rc3+/build/vmlinux)
 7f47c417edf0 [unknown] ([unknown])
 
 Fail to unwind

This patch provides a '--tail-synthesize' option, allows perf to collect
system status when finalizing output file. In resuling output file, the
non-sample events reflect system status when dumping data.

After this patch:
 # perf record -m 4 -e raw_syscalls:* -g --overwrite --switch-output 
--tail-synthesize \
dd if=/dev/zero of=/dev/null

 # perf script -i perf.data.2016061600544998
 dd 27364 [004] 2583244.994464: raw_syscalls:sys_enter: NR 1 (1, ...
 ^^
 Correct comm
   203a18 syscall_trace_enter_phase2+0xfe2001a8 
([kernel.kallsyms])
   203aa5 syscall_trace_enter+0xfe200055 ([kernel.kallsyms])
   203caa do_syscall_64+0xfe2000fa ([kernel.kallsyms])
   b18d83 return_from_SYSCALL_64+0xfe20 ([kernel.kallsyms])
d8e50 __GI___libc_write+0x01d9639f4010 
(/tmp/oxygen_root-w00229757/lib64/libc-2.18.so)
^
Correct unwind

This option doesn't aim to solve this problem completely. If a process
terminates before SIGUSR2, we still lost its COMM and MMAP events. For
example, we can't unwind correctly from the final perf.data we get from
the previous example, because when perf collects the final output file
(when we press C-c), 'dd' has been terminated so its
'/proc//mmap' becomes empty. However, this is a cheaper choice. To
completely solve this problem we need to continously output non-sample
events. To satisify the requirement of daemonization, we need to merge
them periodically. It is possible but requires much more code and cycles.

Automatically select --tail-synthesize when --overwrite is provided.

Signed-off-by: Wang Nan 
Cc: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/Documentation/perf-record.txt |  8 
 tools/perf/builtin-record.c  | 31 +--
 tools/perf/perf.h|  1 +
 3 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt 
b/tools/perf/Documentation/perf-record.txt
index 384c630..69966ab 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -367,6 +367,12 @@ options.
 'perf record --dry-run -e' can act as a BPF script compiler if llvm.dump-obj
 in config file is set to true.
 
+--tail-synthesize::
+Instead of collecting non-sample events (for example, fork, comm, mmap) at
+the beginning of record, collect them during finalizing an output file.
+The collected non-sample events reflects the status of the system when
+record is finished.
+
 --overwrite::
 Makes all events use an overwritable ring buffer. An overwritable ring
 buffer works like a flight recorder: when it gets full, the kernel will
@@ -381,6 +387,8 @@ those fitting in the ring buffer at that moment.
 'overwrite' attribute can also be set or canceled for an event using
 config terms. For example: 'cycles/overwrite/' and 
'instructions/no-overwrite/'.
 
+Implies --tail-synthesize.
+
 SEE ALSO
 
 linkperf:perf-stat[1], linkperf:perf-list[1]
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 4a265e7..19bef09 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -741,13 +741,16 @@ record__finish_output(struct record *rec)
return;
 }
 
-static int record__synthesize_workload(struct record *rec)
+static int record__synthesize_workload(struct record *rec, bool tail)
 {
struct {
struct thread_map map;
struct thread_map_data map_data;
} thread_map;
 
+   if (rec->opts.tail_synthesize != tail)
+   return 0;
+
thread_map.map.nr = 1;
thread_map.map.map[0].pid = rec->evlist->workload.pid;
thread_map.map.map[0].comm = NULL;
@@ -758,7 +761,7 @@ static int record__synthesize_workload(struct record *rec)

[PATCH v10 08/10] perf tools: Enable overwrite settings

2016-06-22 Thread Wang Nan
This patch allows following config terms and option:

Globally setting events to overwrite;

 # perf record --overwrite ...

Set specific events to be overwrite or no-overwrite.

 # perf record --event cycles/overwrite/ ...
 # perf record --event cycles/no-overwrite/ ...

Add missing config terms and update config term array size because the
longest string length is changed.

For overwritable events, automatically select attr.write_backward since
perf requires it to be backward for reading.

Test result:
 # perf record --overwrite -e syscalls:*enter_nanosleep* usleep 1
 [ perf record: Woken up 2 times to write data ]
 [ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
 # perf evlist -v
 syscalls:sys_enter_nanosleep: type: 2, size: 112, config: 0x134, { 
sample_period, sample_freq }: 1, sample_type: IP|TID|TIME|CPU|PERIOD|RAW, 
disabled: 1, inherit: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, 
sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, write_backward: 1
 # Tip: use 'perf evlist --trace-fields' to show fields for tracepoint events

Signed-off-by: Wang Nan 
Signed-off-by: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/Documentation/perf-record.txt | 14 ++
 tools/perf/builtin-record.c  |  1 +
 tools/perf/perf.h|  1 +
 tools/perf/tests/backward-ring-buffer.c  | 15 ++-
 tools/perf/util/evsel.c  | 12 
 tools/perf/util/evsel.h  |  2 ++
 tools/perf/util/parse-events.c   | 20 ++--
 tools/perf/util/parse-events.h   |  2 ++
 tools/perf/util/parse-events.l   |  2 ++
 9 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt 
b/tools/perf/Documentation/perf-record.txt
index 5b46b1d..384c630 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -367,6 +367,20 @@ options.
 'perf record --dry-run -e' can act as a BPF script compiler if llvm.dump-obj
 in config file is set to true.
 
+--overwrite::
+Makes all events use an overwritable ring buffer. An overwritable ring
+buffer works like a flight recorder: when it gets full, the kernel will
+overwrite the oldest records, that thus will never make it to the
+perf.data file.
+
+When '--overwrite' and '--switch-output' are used perf records and drops
+events until it receives a signal, meaning that something unusual was
+detected that warrants taking a snapshot of the most current events,
+those fitting in the ring buffer at that moment.
+
+'overwrite' attribute can also be set or canceled for an event using
+config terms. For example: 'cycles/overwrite/' and 
'instructions/no-overwrite/'.
+
 SEE ALSO
 
 linkperf:perf-stat[1], linkperf:perf-list[1]
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index ba19e9c..4a265e7 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -1539,6 +1539,7 @@ struct option __record_options[] = {
OPT_BOOLEAN_SET('i', "no-inherit", _inherit,
_inherit_set,
"child tasks do not inherit counters"),
+   OPT_BOOLEAN(0, "overwrite", , "use overwrite 
mode"),
OPT_UINTEGER('F', "freq", _freq, "profile at this 
frequency"),
OPT_CALLBACK('m', "mmap-pages", , "pages[,pages]",
 "number of mmap data pages and AUX area tracing mmap 
pages",
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index cd8f1b1..608b42b 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -59,6 +59,7 @@ struct record_opts {
bool record_switch_events;
bool all_kernel;
bool all_user;
+   bool overwrite;
unsigned int freq;
unsigned int mmap_pages;
unsigned int auxtrace_mmap_pages;
diff --git a/tools/perf/tests/backward-ring-buffer.c 
b/tools/perf/tests/backward-ring-buffer.c
index 0b100b8..926e30e 100644
--- a/tools/perf/tests/backward-ring-buffer.c
+++ b/tools/perf/tests/backward-ring-buffer.c
@@ -137,27 +137,24 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
}
 
bzero(_error, sizeof(parse_error));
-   err = parse_events(evlist, "syscalls:sys_enter_prctl", _error);
+   /*
+* Set backward bit, ring buffer should be writing from end. Record
+* it in aux evlist
+*/
+   err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", 
_error);
if (err) {
pr_debug("Failed to parse tracepoint event, try use root\n");
ret = TEST_SKIP;
goto out_delete_evlist;
}
 
-   /*
-* Set backward bit, ring buffer should be 

[PATCH v3] mwifiex: Reduce endian conversion for REG Host Commands

2016-06-22 Thread Prasun Maiti
For multiple REG Host Commands (e.g HostCmd_CMD_802_11_EEPROM_ACCESS,
HostCmd_CMD_MAC_REG_ACCESS etc.) "cpu_to_leX"-converted values are
saved to driver. So, "leX_to_cpu" conversion is required too many
times afterwards in driver.

This patch reduces the endian: conversion without saving "cpu_to_leX"
converted values in driver. This will convert endianness in prepare
command and command response path.

Signed-off-by: Prasun Maiti 
---
Changes in v3:
- Fixed the following warnings:
* sta_ioctl.c:1339:34: warning: comparison of distinct pointer types 
lacks a cast [enabled by default]
* sta_cmdresp.c:821:6: warning: comparison of distinct pointer types 
lacks a cast [enabled by default]

 drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 28 +++-
 drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 37 +++---
 drivers/net/wireless/marvell/mwifiex/sta_ioctl.c   | 21 ++--
 3 files changed, 41 insertions(+), 45 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c 
b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index e436574..9df02ba 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -1130,9 +1130,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
mac_reg = >params.mac_reg;
mac_reg->action = cpu_to_le16(cmd_action);
-   mac_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   mac_reg->value = reg_rw->value;
+   mac_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   mac_reg->value = cpu_to_le32(reg_rw->value);
break;
}
case HostCmd_CMD_BBP_REG_ACCESS:
@@ -1142,9 +1141,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
bbp_reg = >params.bbp_reg;
bbp_reg->action = cpu_to_le16(cmd_action);
-   bbp_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   bbp_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   bbp_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   bbp_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_RF_REG_ACCESS:
@@ -1154,8 +1152,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
rf_reg = >params.rf_reg;
rf_reg->action = cpu_to_le16(cmd_action);
-   rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   rf_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   rf_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   rf_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_PMIC_REG_ACCESS:
@@ -1165,9 +1163,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN);
pmic_reg = >params.pmic_reg;
pmic_reg->action = cpu_to_le16(cmd_action);
-   pmic_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   pmic_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   pmic_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   pmic_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_CAU_REG_ACCESS:
@@ -1177,9 +1174,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
cau_reg = >params.rf_reg;
cau_reg->action = cpu_to_le16(cmd_action);
-   cau_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   cau_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   cau_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   cau_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_802_11_EEPROM_ACCESS:
@@ -1190,8 +1186,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,

cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN);
cmd_eeprom->action = cpu_to_le16(cmd_action);
-   cmd_eeprom->offset = rd_eeprom->offset;
-   cmd_eeprom->byte_count = rd_eeprom->byte_count;
+   cmd_eeprom->offset = cpu_to_le16(rd_eeprom->offset);
+   cmd_eeprom->byte_count = cpu_to_le16(rd_eeprom->byte_count);
cmd_eeprom->value = 0;
break;
}
diff --git 

[PATCH v10 09/10] perf tools: Don't warn about out of order event if write_backward is used

2016-06-22 Thread Wang Nan
If write_backward attribute is set, records are written into kernel
ring buffer from end to beginning, but read from beginning to end.
To avoid 'XX out of order events recorded' warning message (timestamps
of records is in reverse order when using write_backward), suppress the
warning message if write_backward is selected by at lease one event.

Result:

Before this patch:
 # perf record -m 1 -e raw_syscalls:sys_exit/overwrite/ \
-e raw_syscalls:sys_enter \
dd if=/dev/zero of=/dev/null count=300
 300+0 records in
 300+0 records out
 153600 bytes (154 kB) copied, 0.000601617 s, 255 MB/s
 [ perf record: Woken up 5 times to write data ]
 Warning:
 40 out of order events recorded.
 [ perf record: Captured and wrote 0.096 MB perf.data (696 samples) ]

After this patch:
 # perf record -m 1 -e raw_syscalls:sys_exit/overwrite/ \
-e raw_syscalls:sys_enter \
dd if=/dev/zero of=/dev/null count=300
 300+0 records in
 300+0 records out
 153600 bytes (154 kB) copied, 0.000644873 s, 238 MB/s
 [ perf record: Woken up 5 times to write data ]
 [ perf record: Captured and wrote 0.096 MB perf.data (696 samples) ]

Signed-off-by: Wang Nan 
Signed-off-by: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/session.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 43be0c5..0d19530 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1499,10 +1499,27 @@ int perf_session__register_idle_thread(struct 
perf_session *session)
return err;
 }
 
+static void
+perf_session__warn_order(const struct perf_session *session)
+{
+   const struct ordered_events *oe = >ordered_events;
+   struct perf_evsel *evsel;
+   bool should_warn = true;
+
+   evlist__for_each(session->evlist, evsel) {
+   if (evsel->attr.write_backward)
+   should_warn = false;
+   }
+
+   if (!should_warn)
+   return;
+   if (oe->nr_unordered_events != 0)
+   ui__warning("%u out of order events recorded.\n", 
oe->nr_unordered_events);
+}
+
 static void perf_session__warn_about_errors(const struct perf_session *session)
 {
const struct events_stats *stats = >evlist->stats;
-   const struct ordered_events *oe = >ordered_events;
 
if (session->tool->lost == perf_event__process_lost &&
stats->nr_events[PERF_RECORD_LOST] != 0) {
@@ -1559,8 +1576,7 @@ static void perf_session__warn_about_errors(const struct 
perf_session *session)
stats->nr_unprocessable_samples);
}
 
-   if (oe->nr_unordered_events != 0)
-   ui__warning("%u out of order events recorded.\n", 
oe->nr_unordered_events);
+   perf_session__warn_order(session);
 
events_stats__auxtrace_error_warn(stats);
 
-- 
1.8.3.4



[PATCH v10 07/10] perf record: Read from overwritable ring buffer

2016-06-22 Thread Wang Nan
overwrite_evt_state is introduced to reflect the state of overwritable
ring buffers. It is a state machine with 3 states:

.(forbid)_.
| |
| V
 RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY
^  ^  |   ^   |
|  |__(forbid)/   |___(forbid)___/|
| |
 \_(3)___/

 RUNNING  : Overwritable ring buffers are recording
 DATA_PENDING : We are required to collect overwritable ring buffers
 EMPTY: We have collected data from those ring buffers.

 (1): Pause ring buffers for reading
 (2): Read from ring buffers
 (3): Resume ring buffers for recording

We can't avoid this complexity. Since we deliberately drop records from
overwritable ring buffer, there's no way for us to check remaining from
ring buffer itself (by checking head and old pointers). Therefore, we
need DATA_PENDING and EMPTY state to help us recording what we have done
to the ring buffer.

With the above state machine, this patch improves record__mmap_read_all(),
read from overwritable ring buffer when DATA_PENDING state is observed.

Signed-off-by: Wang Nan 
Signed-off-by: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/builtin-record.c | 137 +++-
 1 file changed, 136 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index d1873ee..ba19e9c 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -42,6 +42,30 @@
 #include 
 #include 
 
+/*
+ * State machine of overwrite_evt_state:
+ *
+ *.(forbid)_.
+ *| V
+ * RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY
+ *^  ^  |   ^   |
+ *|  |__(forbid)/   |___(forbid)___/|
+ *| |
+ * \_(3)___/
+ *
+ * RUNNING  : Overwritable ring buffers are recording
+ * DATA_PENDING : We are required to collect overwritable ring buffers
+ * EMPTY: We have collected data from those ring buffers.
+ *
+ * (1): Pause ring buffers for reading
+ * (2): Read from ring buffers
+ * (3): Resume ring buffers for recording
+ */
+enum overwrite_evt_state {
+   OVERWRITE_EVT_RUNNING,
+   OVERWRITE_EVT_DATA_PENDING,
+   OVERWRITE_EVT_EMPTY,
+};
 
 struct record {
struct perf_tooltool;
@@ -61,6 +85,7 @@ struct record {
boolbuildid_all;
booltimestamp_filename;
boolswitch_output;
+   enum overwrite_evt_state overwrite_evt_state;
unsigned long long  samples;
 };
 
@@ -462,6 +487,7 @@ try_again:
 
session->evlist = evlist;
perf_session__set_id_hdr_size(session);
+   rec->overwrite_evt_state = OVERWRITE_EVT_RUNNING;
 out:
return rc;
 }
@@ -542,6 +568,79 @@ static struct perf_event_header finished_round_event = {
.type = PERF_RECORD_FINISHED_ROUND,
 };
 
+static void
+record__toggle_overwrite_evsels(struct record *rec,
+   enum overwrite_evt_state state)
+{
+   struct perf_evlist *evlist = rec->overwrite_evlist;
+   enum overwrite_evt_state old_state = rec->overwrite_evt_state;
+   enum action {
+   NONE,
+   PAUSE,
+   RESUME,
+   } action = NONE;
+
+   switch (old_state) {
+   case OVERWRITE_EVT_RUNNING: {
+   switch (state) {
+   case OVERWRITE_EVT_DATA_PENDING:
+   action = PAUSE;
+   break;
+   case OVERWRITE_EVT_RUNNING:
+   case OVERWRITE_EVT_EMPTY:
+   default:
+   goto state_err;
+   }
+   break;
+   }
+   case OVERWRITE_EVT_DATA_PENDING: {
+   switch (state) {
+   case OVERWRITE_EVT_EMPTY:
+   break;
+   case OVERWRITE_EVT_RUNNING:
+   case OVERWRITE_EVT_DATA_PENDING:
+   default:
+   goto state_err;
+   }
+   break;
+   }
+   case OVERWRITE_EVT_EMPTY: {
+   switch (state) {
+   case OVERWRITE_EVT_RUNNING:
+   action = RESUME;
+   break;
+   case OVERWRITE_EVT_EMPTY:
+   case OVERWRITE_EVT_DATA_PENDING:
+   default:
+   goto state_err;
+   }
+   break;
+   }
+   default:
+   WARN_ONCE(1, "Shouldn't get 

[PATCH v3] mwifiex: Reduce endian conversion for REG Host Commands

2016-06-22 Thread Prasun Maiti
For multiple REG Host Commands (e.g HostCmd_CMD_802_11_EEPROM_ACCESS,
HostCmd_CMD_MAC_REG_ACCESS etc.) "cpu_to_leX"-converted values are
saved to driver. So, "leX_to_cpu" conversion is required too many
times afterwards in driver.

This patch reduces the endian: conversion without saving "cpu_to_leX"
converted values in driver. This will convert endianness in prepare
command and command response path.

Signed-off-by: Prasun Maiti 
---
Changes in v3:
- Fixed the following warnings:
* sta_ioctl.c:1339:34: warning: comparison of distinct pointer types 
lacks a cast [enabled by default]
* sta_cmdresp.c:821:6: warning: comparison of distinct pointer types 
lacks a cast [enabled by default]

 drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 28 +++-
 drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 37 +++---
 drivers/net/wireless/marvell/mwifiex/sta_ioctl.c   | 21 ++--
 3 files changed, 41 insertions(+), 45 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c 
b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index e436574..9df02ba 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -1130,9 +1130,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
mac_reg = >params.mac_reg;
mac_reg->action = cpu_to_le16(cmd_action);
-   mac_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   mac_reg->value = reg_rw->value;
+   mac_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   mac_reg->value = cpu_to_le32(reg_rw->value);
break;
}
case HostCmd_CMD_BBP_REG_ACCESS:
@@ -1142,9 +1141,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
bbp_reg = >params.bbp_reg;
bbp_reg->action = cpu_to_le16(cmd_action);
-   bbp_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   bbp_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   bbp_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   bbp_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_RF_REG_ACCESS:
@@ -1154,8 +1152,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
rf_reg = >params.rf_reg;
rf_reg->action = cpu_to_le16(cmd_action);
-   rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   rf_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   rf_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   rf_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_PMIC_REG_ACCESS:
@@ -1165,9 +1163,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN);
pmic_reg = >params.pmic_reg;
pmic_reg->action = cpu_to_le16(cmd_action);
-   pmic_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   pmic_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   pmic_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   pmic_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_CAU_REG_ACCESS:
@@ -1177,9 +1174,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
cau_reg = >params.rf_reg;
cau_reg->action = cpu_to_le16(cmd_action);
-   cau_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   cau_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   cau_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   cau_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_802_11_EEPROM_ACCESS:
@@ -1190,8 +1186,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,

cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN);
cmd_eeprom->action = cpu_to_le16(cmd_action);
-   cmd_eeprom->offset = rd_eeprom->offset;
-   cmd_eeprom->byte_count = rd_eeprom->byte_count;
+   cmd_eeprom->offset = cpu_to_le16(rd_eeprom->offset);
+   cmd_eeprom->byte_count = cpu_to_le16(rd_eeprom->byte_count);
cmd_eeprom->value = 0;
break;
}
diff --git 

[PATCH v10 09/10] perf tools: Don't warn about out of order event if write_backward is used

2016-06-22 Thread Wang Nan
If write_backward attribute is set, records are written into kernel
ring buffer from end to beginning, but read from beginning to end.
To avoid 'XX out of order events recorded' warning message (timestamps
of records is in reverse order when using write_backward), suppress the
warning message if write_backward is selected by at lease one event.

Result:

Before this patch:
 # perf record -m 1 -e raw_syscalls:sys_exit/overwrite/ \
-e raw_syscalls:sys_enter \
dd if=/dev/zero of=/dev/null count=300
 300+0 records in
 300+0 records out
 153600 bytes (154 kB) copied, 0.000601617 s, 255 MB/s
 [ perf record: Woken up 5 times to write data ]
 Warning:
 40 out of order events recorded.
 [ perf record: Captured and wrote 0.096 MB perf.data (696 samples) ]

After this patch:
 # perf record -m 1 -e raw_syscalls:sys_exit/overwrite/ \
-e raw_syscalls:sys_enter \
dd if=/dev/zero of=/dev/null count=300
 300+0 records in
 300+0 records out
 153600 bytes (154 kB) copied, 0.000644873 s, 238 MB/s
 [ perf record: Woken up 5 times to write data ]
 [ perf record: Captured and wrote 0.096 MB perf.data (696 samples) ]

Signed-off-by: Wang Nan 
Signed-off-by: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/session.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 43be0c5..0d19530 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1499,10 +1499,27 @@ int perf_session__register_idle_thread(struct 
perf_session *session)
return err;
 }
 
+static void
+perf_session__warn_order(const struct perf_session *session)
+{
+   const struct ordered_events *oe = >ordered_events;
+   struct perf_evsel *evsel;
+   bool should_warn = true;
+
+   evlist__for_each(session->evlist, evsel) {
+   if (evsel->attr.write_backward)
+   should_warn = false;
+   }
+
+   if (!should_warn)
+   return;
+   if (oe->nr_unordered_events != 0)
+   ui__warning("%u out of order events recorded.\n", 
oe->nr_unordered_events);
+}
+
 static void perf_session__warn_about_errors(const struct perf_session *session)
 {
const struct events_stats *stats = >evlist->stats;
-   const struct ordered_events *oe = >ordered_events;
 
if (session->tool->lost == perf_event__process_lost &&
stats->nr_events[PERF_RECORD_LOST] != 0) {
@@ -1559,8 +1576,7 @@ static void perf_session__warn_about_errors(const struct 
perf_session *session)
stats->nr_unprocessable_samples);
}
 
-   if (oe->nr_unordered_events != 0)
-   ui__warning("%u out of order events recorded.\n", 
oe->nr_unordered_events);
+   perf_session__warn_order(session);
 
events_stats__auxtrace_error_warn(stats);
 
-- 
1.8.3.4



[PATCH v10 07/10] perf record: Read from overwritable ring buffer

2016-06-22 Thread Wang Nan
overwrite_evt_state is introduced to reflect the state of overwritable
ring buffers. It is a state machine with 3 states:

.(forbid)_.
| |
| V
 RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY
^  ^  |   ^   |
|  |__(forbid)/   |___(forbid)___/|
| |
 \_(3)___/

 RUNNING  : Overwritable ring buffers are recording
 DATA_PENDING : We are required to collect overwritable ring buffers
 EMPTY: We have collected data from those ring buffers.

 (1): Pause ring buffers for reading
 (2): Read from ring buffers
 (3): Resume ring buffers for recording

We can't avoid this complexity. Since we deliberately drop records from
overwritable ring buffer, there's no way for us to check remaining from
ring buffer itself (by checking head and old pointers). Therefore, we
need DATA_PENDING and EMPTY state to help us recording what we have done
to the ring buffer.

With the above state machine, this patch improves record__mmap_read_all(),
read from overwritable ring buffer when DATA_PENDING state is observed.

Signed-off-by: Wang Nan 
Signed-off-by: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/builtin-record.c | 137 +++-
 1 file changed, 136 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index d1873ee..ba19e9c 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -42,6 +42,30 @@
 #include 
 #include 
 
+/*
+ * State machine of overwrite_evt_state:
+ *
+ *.(forbid)_.
+ *| V
+ * RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY
+ *^  ^  |   ^   |
+ *|  |__(forbid)/   |___(forbid)___/|
+ *| |
+ * \_(3)___/
+ *
+ * RUNNING  : Overwritable ring buffers are recording
+ * DATA_PENDING : We are required to collect overwritable ring buffers
+ * EMPTY: We have collected data from those ring buffers.
+ *
+ * (1): Pause ring buffers for reading
+ * (2): Read from ring buffers
+ * (3): Resume ring buffers for recording
+ */
+enum overwrite_evt_state {
+   OVERWRITE_EVT_RUNNING,
+   OVERWRITE_EVT_DATA_PENDING,
+   OVERWRITE_EVT_EMPTY,
+};
 
 struct record {
struct perf_tooltool;
@@ -61,6 +85,7 @@ struct record {
boolbuildid_all;
booltimestamp_filename;
boolswitch_output;
+   enum overwrite_evt_state overwrite_evt_state;
unsigned long long  samples;
 };
 
@@ -462,6 +487,7 @@ try_again:
 
session->evlist = evlist;
perf_session__set_id_hdr_size(session);
+   rec->overwrite_evt_state = OVERWRITE_EVT_RUNNING;
 out:
return rc;
 }
@@ -542,6 +568,79 @@ static struct perf_event_header finished_round_event = {
.type = PERF_RECORD_FINISHED_ROUND,
 };
 
+static void
+record__toggle_overwrite_evsels(struct record *rec,
+   enum overwrite_evt_state state)
+{
+   struct perf_evlist *evlist = rec->overwrite_evlist;
+   enum overwrite_evt_state old_state = rec->overwrite_evt_state;
+   enum action {
+   NONE,
+   PAUSE,
+   RESUME,
+   } action = NONE;
+
+   switch (old_state) {
+   case OVERWRITE_EVT_RUNNING: {
+   switch (state) {
+   case OVERWRITE_EVT_DATA_PENDING:
+   action = PAUSE;
+   break;
+   case OVERWRITE_EVT_RUNNING:
+   case OVERWRITE_EVT_EMPTY:
+   default:
+   goto state_err;
+   }
+   break;
+   }
+   case OVERWRITE_EVT_DATA_PENDING: {
+   switch (state) {
+   case OVERWRITE_EVT_EMPTY:
+   break;
+   case OVERWRITE_EVT_RUNNING:
+   case OVERWRITE_EVT_DATA_PENDING:
+   default:
+   goto state_err;
+   }
+   break;
+   }
+   case OVERWRITE_EVT_EMPTY: {
+   switch (state) {
+   case OVERWRITE_EVT_RUNNING:
+   action = RESUME;
+   break;
+   case OVERWRITE_EVT_EMPTY:
+   case OVERWRITE_EVT_DATA_PENDING:
+   default:
+   goto state_err;
+   }
+   break;
+   }
+   default:
+   WARN_ONCE(1, "Shouldn't get there\n");
+   }
+
+   rec->overwrite_evt_state = state;
+
+   if (!evlist)
+   return;
+
+   switch (action) 

[PATCH v10 08/10] perf tools: Enable overwrite settings

2016-06-22 Thread Wang Nan
This patch allows following config terms and option:

Globally setting events to overwrite;

 # perf record --overwrite ...

Set specific events to be overwrite or no-overwrite.

 # perf record --event cycles/overwrite/ ...
 # perf record --event cycles/no-overwrite/ ...

Add missing config terms and update config term array size because the
longest string length is changed.

For overwritable events, automatically select attr.write_backward since
perf requires it to be backward for reading.

Test result:
 # perf record --overwrite -e syscalls:*enter_nanosleep* usleep 1
 [ perf record: Woken up 2 times to write data ]
 [ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
 # perf evlist -v
 syscalls:sys_enter_nanosleep: type: 2, size: 112, config: 0x134, { 
sample_period, sample_freq }: 1, sample_type: IP|TID|TIME|CPU|PERIOD|RAW, 
disabled: 1, inherit: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, 
sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, write_backward: 1
 # Tip: use 'perf evlist --trace-fields' to show fields for tracepoint events

Signed-off-by: Wang Nan 
Signed-off-by: He Kuang 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/Documentation/perf-record.txt | 14 ++
 tools/perf/builtin-record.c  |  1 +
 tools/perf/perf.h|  1 +
 tools/perf/tests/backward-ring-buffer.c  | 15 ++-
 tools/perf/util/evsel.c  | 12 
 tools/perf/util/evsel.h  |  2 ++
 tools/perf/util/parse-events.c   | 20 ++--
 tools/perf/util/parse-events.h   |  2 ++
 tools/perf/util/parse-events.l   |  2 ++
 9 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt 
b/tools/perf/Documentation/perf-record.txt
index 5b46b1d..384c630 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -367,6 +367,20 @@ options.
 'perf record --dry-run -e' can act as a BPF script compiler if llvm.dump-obj
 in config file is set to true.
 
+--overwrite::
+Makes all events use an overwritable ring buffer. An overwritable ring
+buffer works like a flight recorder: when it gets full, the kernel will
+overwrite the oldest records, that thus will never make it to the
+perf.data file.
+
+When '--overwrite' and '--switch-output' are used perf records and drops
+events until it receives a signal, meaning that something unusual was
+detected that warrants taking a snapshot of the most current events,
+those fitting in the ring buffer at that moment.
+
+'overwrite' attribute can also be set or canceled for an event using
+config terms. For example: 'cycles/overwrite/' and 
'instructions/no-overwrite/'.
+
 SEE ALSO
 
 linkperf:perf-stat[1], linkperf:perf-list[1]
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index ba19e9c..4a265e7 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -1539,6 +1539,7 @@ struct option __record_options[] = {
OPT_BOOLEAN_SET('i', "no-inherit", _inherit,
_inherit_set,
"child tasks do not inherit counters"),
+   OPT_BOOLEAN(0, "overwrite", , "use overwrite 
mode"),
OPT_UINTEGER('F', "freq", _freq, "profile at this 
frequency"),
OPT_CALLBACK('m', "mmap-pages", , "pages[,pages]",
 "number of mmap data pages and AUX area tracing mmap 
pages",
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index cd8f1b1..608b42b 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -59,6 +59,7 @@ struct record_opts {
bool record_switch_events;
bool all_kernel;
bool all_user;
+   bool overwrite;
unsigned int freq;
unsigned int mmap_pages;
unsigned int auxtrace_mmap_pages;
diff --git a/tools/perf/tests/backward-ring-buffer.c 
b/tools/perf/tests/backward-ring-buffer.c
index 0b100b8..926e30e 100644
--- a/tools/perf/tests/backward-ring-buffer.c
+++ b/tools/perf/tests/backward-ring-buffer.c
@@ -137,27 +137,24 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
}
 
bzero(_error, sizeof(parse_error));
-   err = parse_events(evlist, "syscalls:sys_enter_prctl", _error);
+   /*
+* Set backward bit, ring buffer should be writing from end. Record
+* it in aux evlist
+*/
+   err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", 
_error);
if (err) {
pr_debug("Failed to parse tracepoint event, try use root\n");
ret = TEST_SKIP;
goto out_delete_evlist;
}
 
-   /*
-* Set backward bit, ring buffer should be writing from end. Record
-* it in aux evlist
-*/
-   perf_evlist__last(evlist)->overwrite = true;
-   

[PATCH v10 00/10] perf tools: Support overwritable ring buffer

2016-06-22 Thread Wang Nan
This patch set enables daemonized perf recording by utilizing
overwritable backward ring buffer. With this feature one can
put perf background, and dump ring buffer records by a SIGUSR2
when he/she find something unusual. For example, following
command record system calls, schedule events and samples on cpu cycles
continously:

 # perf record -g -e cycles -e raw_syscalls:*/call-graph=no/ \
  -e sched:sched_switch/call-graph=no/ \
  --switch-output --overwrite -a

Then by sending SIGUSR2 to perf when lagging is happen, we get multiple
perf.data output, each of them correspond a abnormal event, and the data
size is reasonable:

 # ls -l ./perf.data*
 -rw--- 1 root root 5122165 May 13 23:51 ./perf.data.2016051323511683
 -rw--- 1 root root 5135093 May 13 23:51 ./perf.data.2016051323512107
 -rw--- 1 root root 5135213 May 13 23:51 ./perf.data.2016051323512215
 -rw--- 1 root root 5135157 May 13 23:51 ./perf.data.2016051323512387

v1 -> v2: Totally redesign: drop the principle of 'channal', use
  auxiliary evlist instead. Fix missing documentation.

v2 -> v3: Rename perf_evlist__toggle_paused() to perf_evlist__pause/resume.

v3 -> v4: Update commit message to describe auxiliary evlist more clearly.

v4 -> v5: Reorder commits, ensure '--overwrite' works right after perf
  support the option.
  Add test cases for auxiliary evlist.
  Avoid bug if main evlist is empty.

v5 -> v6: Improve filter pollfd related code.

v6 -> v7: Rebase to newest perf/core.

v7 -> v8: Unmap mmaps from parent and children in
  perf_evlist__munmap_filtered(), hide more detail of aux evlist.
  Add --tail-synthesize, do synthesize at the end of perf.data.

v8 -> v9: Beautify code of test case, make patch set more granular,
  improve documentation.

v9 -> v10: Make patch set more granular: extract preparation code to
   patch 1-3.

Wang Nan (10):
  perf record: Prepare mmap multiple evlists
  perf record: Prepare reading from multiple evlists in
record__mmap_read_all()
  perf record: Prepare picking perf_event_mmap_page from multiple
evlists
  perf evlist: Introduce aux evlist
  perf tests: Add testcase for auxiliary evlist
  perf record: Introduce rec->overwrite_evlist for overwritable events
  perf record: Read from overwritable ring buffer
  perf tools: Enable overwrite settings
  perf tools: Don't warn about out of order event if write_backward is
used
  perf tools: Add --tail-synthesize option

 tools/perf/Documentation/perf-record.txt |  22 +++
 tools/perf/builtin-record.c  | 325 +++
 tools/perf/perf.h|   2 +
 tools/perf/tests/backward-ring-buffer.c  |  89 +++--
 tools/perf/util/evlist.c |  49 +++--
 tools/perf/util/evlist.h |  20 ++
 tools/perf/util/evsel.c  |  12 ++
 tools/perf/util/evsel.h  |   2 +
 tools/perf/util/parse-events.c   |  20 +-
 tools/perf/util/parse-events.h   |   2 +
 tools/perf/util/parse-events.l   |   2 +
 tools/perf/util/session.c|  22 ++-
 12 files changed, 495 insertions(+), 72 deletions(-)

-- 
1.8.3.4



[PATCH v10 00/10] perf tools: Support overwritable ring buffer

2016-06-22 Thread Wang Nan
This patch set enables daemonized perf recording by utilizing
overwritable backward ring buffer. With this feature one can
put perf background, and dump ring buffer records by a SIGUSR2
when he/she find something unusual. For example, following
command record system calls, schedule events and samples on cpu cycles
continously:

 # perf record -g -e cycles -e raw_syscalls:*/call-graph=no/ \
  -e sched:sched_switch/call-graph=no/ \
  --switch-output --overwrite -a

Then by sending SIGUSR2 to perf when lagging is happen, we get multiple
perf.data output, each of them correspond a abnormal event, and the data
size is reasonable:

 # ls -l ./perf.data*
 -rw--- 1 root root 5122165 May 13 23:51 ./perf.data.2016051323511683
 -rw--- 1 root root 5135093 May 13 23:51 ./perf.data.2016051323512107
 -rw--- 1 root root 5135213 May 13 23:51 ./perf.data.2016051323512215
 -rw--- 1 root root 5135157 May 13 23:51 ./perf.data.2016051323512387

v1 -> v2: Totally redesign: drop the principle of 'channal', use
  auxiliary evlist instead. Fix missing documentation.

v2 -> v3: Rename perf_evlist__toggle_paused() to perf_evlist__pause/resume.

v3 -> v4: Update commit message to describe auxiliary evlist more clearly.

v4 -> v5: Reorder commits, ensure '--overwrite' works right after perf
  support the option.
  Add test cases for auxiliary evlist.
  Avoid bug if main evlist is empty.

v5 -> v6: Improve filter pollfd related code.

v6 -> v7: Rebase to newest perf/core.

v7 -> v8: Unmap mmaps from parent and children in
  perf_evlist__munmap_filtered(), hide more detail of aux evlist.
  Add --tail-synthesize, do synthesize at the end of perf.data.

v8 -> v9: Beautify code of test case, make patch set more granular,
  improve documentation.

v9 -> v10: Make patch set more granular: extract preparation code to
   patch 1-3.

Wang Nan (10):
  perf record: Prepare mmap multiple evlists
  perf record: Prepare reading from multiple evlists in
record__mmap_read_all()
  perf record: Prepare picking perf_event_mmap_page from multiple
evlists
  perf evlist: Introduce aux evlist
  perf tests: Add testcase for auxiliary evlist
  perf record: Introduce rec->overwrite_evlist for overwritable events
  perf record: Read from overwritable ring buffer
  perf tools: Enable overwrite settings
  perf tools: Don't warn about out of order event if write_backward is
used
  perf tools: Add --tail-synthesize option

 tools/perf/Documentation/perf-record.txt |  22 +++
 tools/perf/builtin-record.c  | 325 +++
 tools/perf/perf.h|   2 +
 tools/perf/tests/backward-ring-buffer.c  |  89 +++--
 tools/perf/util/evlist.c |  49 +++--
 tools/perf/util/evlist.h |  20 ++
 tools/perf/util/evsel.c  |  12 ++
 tools/perf/util/evsel.h  |   2 +
 tools/perf/util/parse-events.c   |  20 +-
 tools/perf/util/parse-events.h   |   2 +
 tools/perf/util/parse-events.l   |   2 +
 tools/perf/util/session.c|  22 ++-
 12 files changed, 495 insertions(+), 72 deletions(-)

-- 
1.8.3.4



[PATCH v10 04/10] perf evlist: Introduce aux evlist

2016-06-22 Thread Wang Nan
An auxiliary evlist is created by perf_evlist__new_aux() using an
existing evlist as its parent. An auxiliary evlist can have its own
'struct perf_mmap', but can't have any other data. User should use its
parent instead when accessing other data.

Auxiliary evlists are containers of 'struct perf_mmap'. It is introduced
to allow its parent evlist to map different events into separated mmaps.

Following commits create an auxiliary evlist for overwritable
events, because overwritable events need a read only and backwards ring
buffer, which is different from normal events.

To achieve this goal, this patch carefully changes 'evlist' to
'evlist->parent' in all functions in the path of 'perf_evlist__mmap_ex',
except 'evlist->mmap' related operations, to make sure all evlist
modifications (like pollfd and event id hash tables) goes to original
evlist.

A 'evlist->parent' pointer is added to 'struct perf_evlist' and points to
the evlist itself for normal evlists.

Children of one evlist are linked into it so one can find all children
from its parent.

To avoid potential complexity, forbid creating aux evlist from another
aux evlist.

Improve perf_evlist__munmap_filtered(), so when recording, if an event
is terminated, unmap mmaps, from parent and children.

Signed-off-by: Wang Nan 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/evlist.c | 49 +---
 tools/perf/util/evlist.h | 12 
 2 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index fcb8f1f..ef2e920 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -41,10 +41,12 @@ void perf_evlist__init(struct perf_evlist *evlist, struct 
cpu_map *cpus,
for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
INIT_HLIST_HEAD(>heads[i]);
INIT_LIST_HEAD(>entries);
+   INIT_LIST_HEAD(>children);
perf_evlist__set_maps(evlist, cpus, threads);
fdarray__init(>pollfd, 64);
evlist->workload.pid = -1;
evlist->backward = false;
+   evlist->parent = evlist;
 }
 
 struct perf_evlist *perf_evlist__new(void)
@@ -490,13 +492,17 @@ static void perf_evlist__munmap_filtered(struct fdarray 
*fda, int fd,
 void *arg __maybe_unused)
 {
struct perf_evlist *evlist = container_of(fda, struct perf_evlist, 
pollfd);
+   struct perf_evlist *child;
 
perf_evlist__mmap_put(evlist, fda->priv[fd].idx);
+   list_for_each_entry(child, >children, list)
+   perf_evlist__mmap_put(child, fda->priv[fd].idx);
+
 }
 
 int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short 
revents_and_mask)
 {
-   return fdarray__filter(>pollfd, revents_and_mask,
+   return fdarray__filter(>parent->pollfd, revents_and_mask,
   perf_evlist__munmap_filtered, NULL);
 }
 
@@ -1015,7 +1021,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist 
*evlist, int idx,
struct perf_evsel *evsel;
int revent;
 
-   evlist__for_each(evlist, evsel) {
+   evlist__for_each(evlist->parent, evsel) {
int fd;
 
if (evsel->overwrite != (evlist->overwrite && evlist->backward))
@@ -1047,16 +1053,16 @@ static int perf_evlist__mmap_per_evsel(struct 
perf_evlist *evlist, int idx,
 * Therefore don't add it for polling.
 */
if (!evsel->system_wide &&
-   __perf_evlist__add_pollfd(evlist, fd, idx, revent) < 0) {
+   __perf_evlist__add_pollfd(evlist->parent, fd, idx, revent) 
< 0) {
perf_evlist__mmap_put(evlist, idx);
return -1;
}
 
if (evsel->attr.read_format & PERF_FORMAT_ID) {
-   if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread,
+   if (perf_evlist__id_add_fd(evlist->parent, evsel, cpu, 
thread,
   fd) < 0)
return -1;
-   perf_evlist__set_sid_idx(evlist, evsel, idx, cpu,
+   perf_evlist__set_sid_idx(evlist->parent, evsel, idx, 
cpu,
 thread);
}
}
@@ -1097,13 +1103,13 @@ static int perf_evlist__mmap_per_thread(struct 
perf_evlist *evlist,
struct mmap_params *mp)
 {
int thread;
-   int nr_threads = thread_map__nr(evlist->threads);
+   int nr_threads = thread_map__nr(evlist->parent->threads);
 
pr_debug2("perf event ring buffer mmapped per thread\n");
for (thread = 0; thread < nr_threads; thread++) {
int output 

[PATCH v10 04/10] perf evlist: Introduce aux evlist

2016-06-22 Thread Wang Nan
An auxiliary evlist is created by perf_evlist__new_aux() using an
existing evlist as its parent. An auxiliary evlist can have its own
'struct perf_mmap', but can't have any other data. User should use its
parent instead when accessing other data.

Auxiliary evlists are containers of 'struct perf_mmap'. It is introduced
to allow its parent evlist to map different events into separated mmaps.

Following commits create an auxiliary evlist for overwritable
events, because overwritable events need a read only and backwards ring
buffer, which is different from normal events.

To achieve this goal, this patch carefully changes 'evlist' to
'evlist->parent' in all functions in the path of 'perf_evlist__mmap_ex',
except 'evlist->mmap' related operations, to make sure all evlist
modifications (like pollfd and event id hash tables) goes to original
evlist.

A 'evlist->parent' pointer is added to 'struct perf_evlist' and points to
the evlist itself for normal evlists.

Children of one evlist are linked into it so one can find all children
from its parent.

To avoid potential complexity, forbid creating aux evlist from another
aux evlist.

Improve perf_evlist__munmap_filtered(), so when recording, if an event
is terminated, unmap mmaps, from parent and children.

Signed-off-by: Wang Nan 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/evlist.c | 49 +---
 tools/perf/util/evlist.h | 12 
 2 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index fcb8f1f..ef2e920 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -41,10 +41,12 @@ void perf_evlist__init(struct perf_evlist *evlist, struct 
cpu_map *cpus,
for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
INIT_HLIST_HEAD(>heads[i]);
INIT_LIST_HEAD(>entries);
+   INIT_LIST_HEAD(>children);
perf_evlist__set_maps(evlist, cpus, threads);
fdarray__init(>pollfd, 64);
evlist->workload.pid = -1;
evlist->backward = false;
+   evlist->parent = evlist;
 }
 
 struct perf_evlist *perf_evlist__new(void)
@@ -490,13 +492,17 @@ static void perf_evlist__munmap_filtered(struct fdarray 
*fda, int fd,
 void *arg __maybe_unused)
 {
struct perf_evlist *evlist = container_of(fda, struct perf_evlist, 
pollfd);
+   struct perf_evlist *child;
 
perf_evlist__mmap_put(evlist, fda->priv[fd].idx);
+   list_for_each_entry(child, >children, list)
+   perf_evlist__mmap_put(child, fda->priv[fd].idx);
+
 }
 
 int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short 
revents_and_mask)
 {
-   return fdarray__filter(>pollfd, revents_and_mask,
+   return fdarray__filter(>parent->pollfd, revents_and_mask,
   perf_evlist__munmap_filtered, NULL);
 }
 
@@ -1015,7 +1021,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist 
*evlist, int idx,
struct perf_evsel *evsel;
int revent;
 
-   evlist__for_each(evlist, evsel) {
+   evlist__for_each(evlist->parent, evsel) {
int fd;
 
if (evsel->overwrite != (evlist->overwrite && evlist->backward))
@@ -1047,16 +1053,16 @@ static int perf_evlist__mmap_per_evsel(struct 
perf_evlist *evlist, int idx,
 * Therefore don't add it for polling.
 */
if (!evsel->system_wide &&
-   __perf_evlist__add_pollfd(evlist, fd, idx, revent) < 0) {
+   __perf_evlist__add_pollfd(evlist->parent, fd, idx, revent) 
< 0) {
perf_evlist__mmap_put(evlist, idx);
return -1;
}
 
if (evsel->attr.read_format & PERF_FORMAT_ID) {
-   if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread,
+   if (perf_evlist__id_add_fd(evlist->parent, evsel, cpu, 
thread,
   fd) < 0)
return -1;
-   perf_evlist__set_sid_idx(evlist, evsel, idx, cpu,
+   perf_evlist__set_sid_idx(evlist->parent, evsel, idx, 
cpu,
 thread);
}
}
@@ -1097,13 +1103,13 @@ static int perf_evlist__mmap_per_thread(struct 
perf_evlist *evlist,
struct mmap_params *mp)
 {
int thread;
-   int nr_threads = thread_map__nr(evlist->threads);
+   int nr_threads = thread_map__nr(evlist->parent->threads);
 
pr_debug2("perf event ring buffer mmapped per thread\n");
for (thread = 0; thread < nr_threads; thread++) {
int output = -1;
 
-   auxtrace_mmap_params__set_idx(>auxtrace_mp, evlist, thread,
+   

Re: [PATCH V4 1/3] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-06-22 Thread
From: Rui Wang 

On Wed, June 22, 2016 11:15 PM Bjorn Helgaas wrote:
> [...]
> > @@ -1779,8 +1780,12 @@ void __init
> > pci_assign_unassigned_resources(void)
> >  {
> > struct pci_bus *root_bus;
> >
> > -   list_for_each_entry(root_bus, _root_buses, node)
> > +   list_for_each_entry(root_bus, _root_buses, node) {
> > pci_assign_unassigned_root_bus_resources(root_bus);
> > +#ifdef CONFIG_X86
> > +   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
> > +#endif
> 
> Doesn't this do the right thing even if you omit the #ifdefs, since you
> define a stub function below?
> 

No. Without the '#ifdef CONFIG_X86' it breaks MIPS arch. The stub function is
within 'ifdef CONFIG_ACPI'. On archs without ACPI it doesn't compile due to
'undefined reference to acpi_ioapic_add'.

Thanks
Rui


Re: [PATCH V4 1/3] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-06-22 Thread
From: Rui Wang 

On Wed, June 22, 2016 11:15 PM Bjorn Helgaas wrote:
> [...]
> > @@ -1779,8 +1780,12 @@ void __init
> > pci_assign_unassigned_resources(void)
> >  {
> > struct pci_bus *root_bus;
> >
> > -   list_for_each_entry(root_bus, _root_buses, node)
> > +   list_for_each_entry(root_bus, _root_buses, node) {
> > pci_assign_unassigned_root_bus_resources(root_bus);
> > +#ifdef CONFIG_X86
> > +   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
> > +#endif
> 
> Doesn't this do the right thing even if you omit the #ifdefs, since you
> define a stub function below?
> 

No. Without the '#ifdef CONFIG_X86' it breaks MIPS arch. The stub function is
within 'ifdef CONFIG_ACPI'. On archs without ACPI it doesn't compile due to
'undefined reference to acpi_ioapic_add'.

Thanks
Rui


Re: [PATCH] mmc: core: add auto bkops support

2016-06-22 Thread Adrian Hunter
On 23/06/16 04:33, Shawn Lin wrote:
> 在 2016/6/22 22:08, Alex Lemberg 写道:
>> HI Shawn,
>>
>> On 6/21/16, 4:44 AM, "Shawn Lin"  wrote:
>>
>>> On 2016/6/20 21:33, Alex Lemberg wrote:
 Hi Shawn,

 […]

>>> +
>>> +static int mmc_stop_auto_bkops(struct mmc_card *card)
>>> +{
>>> +int err = 0;
>>> +
>>> +if (!card->ext_csd.auto_bkops_en)
>>> +return 0;
>>> +
>>
>> Shouldn’t the BKOPS_STATUS be checked prior to disabling the BKOPS
>> activity of the device?
>>
>
> Hrmm.. I read the whole section of spec for it, and I did find this
> requirement for manul bkops but not for the auto one. So what should we
> do if using the auto one?
>

 In case of AUTO BKOPS, the eMMC Device should perform internal GC
 in the same way as in case of MANUAL BKOPS.
 The only difference is a host awareness.
>>>
>>> agree.
>>>
 Although there is no requirement in the spec, I think the driver can
 give some time to the device to perform/complete its internal GC during
 the idle time.
 Thus I think we can check the BKOPS_STATUS on Runtime suspend.
>>>
>>> We shouldn't diable bkops on *runtime* suspend as it's just the right
>>> time for firmware to do GC. We could consider to check and wait for
>>> the status when doing poweroff, although it seems firmware should be
>>> able to accept the disable cmd and deal the on-going work perfectly
>>> when doing bkops without host's awareness, just the same way as suddent
>>> power loss cases.
>>
>> If I am not wrong, in current implementation of runtime suspend,
>> the driver stops BKOPS (send HPI) just before sending sleep command,
>> see _mmc_suspend(), depends on “MMC_CAP_AGGRESSIVE_PM” flag.
>> In this case, the eMMC device will not have enough time to perform internal
>> BKOPS in both – Manual and Auto BKOPS configurations.
>>
> 
> ye, so it seems a pre-exiting issue before introducing auto bkops?
> I think we can push another patch to improve it but not handling
> it for this $SUBJECT, does it sound ok to you?

Runtime suspend for eMMC has a default auto-suspend delay of 3 seconds
(refer mmc_blk_probe()).  Isn't that when auto bkops would happen?

> 
>> For the poweroff, it should be OK with a current implementation of
>> PON (mmc_poweroff_notify())
>>
>>>
>>> Also I don't know whether the firmware will reflect its status on
>>> BKOPS_STATUS or not when enabling the auto one. I will do more test.
>>>
>>> Anyway, thanks for sharing your thought.
>>> Also Adrian point out that currently we trigger manual bkosp from
>>> userspace via mmc-utils, and I agreed we shouldn't force kernel stack
>>> to enable it defaultly. So I'm prone not to update this $SUBJECT and
>>> migrate it to mmc-utils later.
>>>

 […]

 Thanks,
 Alex

>>>
>>>
>>> -- 
>>> Best Regards
>>> Shawn Lin
>>>
>>
> 
> 



Re: [PATCH] mmc: core: add auto bkops support

2016-06-22 Thread Adrian Hunter
On 23/06/16 04:33, Shawn Lin wrote:
> 在 2016/6/22 22:08, Alex Lemberg 写道:
>> HI Shawn,
>>
>> On 6/21/16, 4:44 AM, "Shawn Lin"  wrote:
>>
>>> On 2016/6/20 21:33, Alex Lemberg wrote:
 Hi Shawn,

 […]

>>> +
>>> +static int mmc_stop_auto_bkops(struct mmc_card *card)
>>> +{
>>> +int err = 0;
>>> +
>>> +if (!card->ext_csd.auto_bkops_en)
>>> +return 0;
>>> +
>>
>> Shouldn’t the BKOPS_STATUS be checked prior to disabling the BKOPS
>> activity of the device?
>>
>
> Hrmm.. I read the whole section of spec for it, and I did find this
> requirement for manul bkops but not for the auto one. So what should we
> do if using the auto one?
>

 In case of AUTO BKOPS, the eMMC Device should perform internal GC
 in the same way as in case of MANUAL BKOPS.
 The only difference is a host awareness.
>>>
>>> agree.
>>>
 Although there is no requirement in the spec, I think the driver can
 give some time to the device to perform/complete its internal GC during
 the idle time.
 Thus I think we can check the BKOPS_STATUS on Runtime suspend.
>>>
>>> We shouldn't diable bkops on *runtime* suspend as it's just the right
>>> time for firmware to do GC. We could consider to check and wait for
>>> the status when doing poweroff, although it seems firmware should be
>>> able to accept the disable cmd and deal the on-going work perfectly
>>> when doing bkops without host's awareness, just the same way as suddent
>>> power loss cases.
>>
>> If I am not wrong, in current implementation of runtime suspend,
>> the driver stops BKOPS (send HPI) just before sending sleep command,
>> see _mmc_suspend(), depends on “MMC_CAP_AGGRESSIVE_PM” flag.
>> In this case, the eMMC device will not have enough time to perform internal
>> BKOPS in both – Manual and Auto BKOPS configurations.
>>
> 
> ye, so it seems a pre-exiting issue before introducing auto bkops?
> I think we can push another patch to improve it but not handling
> it for this $SUBJECT, does it sound ok to you?

Runtime suspend for eMMC has a default auto-suspend delay of 3 seconds
(refer mmc_blk_probe()).  Isn't that when auto bkops would happen?

> 
>> For the poweroff, it should be OK with a current implementation of
>> PON (mmc_poweroff_notify())
>>
>>>
>>> Also I don't know whether the firmware will reflect its status on
>>> BKOPS_STATUS or not when enabling the auto one. I will do more test.
>>>
>>> Anyway, thanks for sharing your thought.
>>> Also Adrian point out that currently we trigger manual bkosp from
>>> userspace via mmc-utils, and I agreed we shouldn't force kernel stack
>>> to enable it defaultly. So I'm prone not to update this $SUBJECT and
>>> migrate it to mmc-utils later.
>>>

 […]

 Thanks,
 Alex

>>>
>>>
>>> -- 
>>> Best Regards
>>> Shawn Lin
>>>
>>
> 
> 



[PATCH v3] mwifiex: Reduce endian conversion for REG Host Commands

2016-06-22 Thread Prasun Maiti
For multiple REG Host Commands (e.g HostCmd_CMD_802_11_EEPROM_ACCESS,
HostCmd_CMD_MAC_REG_ACCESS etc.) "cpu_to_leX"-converted values are
saved to driver. So, "leX_to_cpu" conversion is required too many
times afterwards in driver.

This patch reduces the endian: conversion without saving "cpu_to_leX"
converted values in driver. This will convert endianness in prepare
command and command response path.

Signed-off-by: Prasun Maiti 
---
Changes in v3:
- Fixed the following warnings:
* sta_ioctl.c:1339:34: warning: comparison of distinct pointer types 
lacks a cast [enabled by default]
* sta_cmdresp.c:821:6: warning: comparison of distinct pointer types 
lacks a cast [enabled by default]

 drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 28 +++-
 drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 37 +++---
 drivers/net/wireless/marvell/mwifiex/sta_ioctl.c   | 21 ++--
 3 files changed, 41 insertions(+), 45 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c 
b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index e436574..9df02ba 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -1130,9 +1130,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
mac_reg = >params.mac_reg;
mac_reg->action = cpu_to_le16(cmd_action);
-   mac_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   mac_reg->value = reg_rw->value;
+   mac_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   mac_reg->value = cpu_to_le32(reg_rw->value);
break;
}
case HostCmd_CMD_BBP_REG_ACCESS:
@@ -1142,9 +1141,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
bbp_reg = >params.bbp_reg;
bbp_reg->action = cpu_to_le16(cmd_action);
-   bbp_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   bbp_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   bbp_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   bbp_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_RF_REG_ACCESS:
@@ -1154,8 +1152,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
rf_reg = >params.rf_reg;
rf_reg->action = cpu_to_le16(cmd_action);
-   rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   rf_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   rf_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   rf_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_PMIC_REG_ACCESS:
@@ -1165,9 +1163,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN);
pmic_reg = >params.pmic_reg;
pmic_reg->action = cpu_to_le16(cmd_action);
-   pmic_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   pmic_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   pmic_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   pmic_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_CAU_REG_ACCESS:
@@ -1177,9 +1174,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
cau_reg = >params.rf_reg;
cau_reg->action = cpu_to_le16(cmd_action);
-   cau_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   cau_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   cau_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   cau_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_802_11_EEPROM_ACCESS:
@@ -1190,8 +1186,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,

cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN);
cmd_eeprom->action = cpu_to_le16(cmd_action);
-   cmd_eeprom->offset = rd_eeprom->offset;
-   cmd_eeprom->byte_count = rd_eeprom->byte_count;
+   cmd_eeprom->offset = cpu_to_le16(rd_eeprom->offset);
+   cmd_eeprom->byte_count = cpu_to_le16(rd_eeprom->byte_count);
cmd_eeprom->value = 0;
break;
}
diff --git 

[PATCH v3] mwifiex: Reduce endian conversion for REG Host Commands

2016-06-22 Thread Prasun Maiti
For multiple REG Host Commands (e.g HostCmd_CMD_802_11_EEPROM_ACCESS,
HostCmd_CMD_MAC_REG_ACCESS etc.) "cpu_to_leX"-converted values are
saved to driver. So, "leX_to_cpu" conversion is required too many
times afterwards in driver.

This patch reduces the endian: conversion without saving "cpu_to_leX"
converted values in driver. This will convert endianness in prepare
command and command response path.

Signed-off-by: Prasun Maiti 
---
Changes in v3:
- Fixed the following warnings:
* sta_ioctl.c:1339:34: warning: comparison of distinct pointer types 
lacks a cast [enabled by default]
* sta_cmdresp.c:821:6: warning: comparison of distinct pointer types 
lacks a cast [enabled by default]

 drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 28 +++-
 drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 37 +++---
 drivers/net/wireless/marvell/mwifiex/sta_ioctl.c   | 21 ++--
 3 files changed, 41 insertions(+), 45 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c 
b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index e436574..9df02ba 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -1130,9 +1130,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
mac_reg = >params.mac_reg;
mac_reg->action = cpu_to_le16(cmd_action);
-   mac_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   mac_reg->value = reg_rw->value;
+   mac_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   mac_reg->value = cpu_to_le32(reg_rw->value);
break;
}
case HostCmd_CMD_BBP_REG_ACCESS:
@@ -1142,9 +1141,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
bbp_reg = >params.bbp_reg;
bbp_reg->action = cpu_to_le16(cmd_action);
-   bbp_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   bbp_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   bbp_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   bbp_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_RF_REG_ACCESS:
@@ -1154,8 +1152,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
rf_reg = >params.rf_reg;
rf_reg->action = cpu_to_le16(cmd_action);
-   rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   rf_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   rf_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   rf_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_PMIC_REG_ACCESS:
@@ -1165,9 +1163,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN);
pmic_reg = >params.pmic_reg;
pmic_reg->action = cpu_to_le16(cmd_action);
-   pmic_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   pmic_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   pmic_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   pmic_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_CAU_REG_ACCESS:
@@ -1177,9 +1174,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,
cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
cau_reg = >params.rf_reg;
cau_reg->action = cpu_to_le16(cmd_action);
-   cau_reg->offset =
-   cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
-   cau_reg->value = (u8) le32_to_cpu(reg_rw->value);
+   cau_reg->offset = cpu_to_le16((u16) reg_rw->offset);
+   cau_reg->value = (u8) reg_rw->value;
break;
}
case HostCmd_CMD_802_11_EEPROM_ACCESS:
@@ -1190,8 +1186,8 @@ static int mwifiex_cmd_reg_access(struct 
host_cmd_ds_command *cmd,

cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN);
cmd_eeprom->action = cpu_to_le16(cmd_action);
-   cmd_eeprom->offset = rd_eeprom->offset;
-   cmd_eeprom->byte_count = rd_eeprom->byte_count;
+   cmd_eeprom->offset = cpu_to_le16(rd_eeprom->offset);
+   cmd_eeprom->byte_count = cpu_to_le16(rd_eeprom->byte_count);
cmd_eeprom->value = 0;
break;
}
diff --git 

Re: [PATCH v4] tools/perf: Fix the mask in regs_dump__printf and print_sample_iregs

2016-06-22 Thread Yury Norov
On Thu, Jun 23, 2016 at 10:31:16AM +0530, Madhavan Srinivasan wrote:
> When decoding the perf_regs mask in regs_dump__printf(),
> we loop through the mask using find_first_bit and find_next_bit functions.
> "mask" is of type "u64", but sent as a "unsigned long *" to
> lib functions along with sizeof().
> 
> While the exisitng code works fine in most of the case,
> the logic is broken when using a 32bit perf on a 64bit kernel (Big Endian).
> When reading u64 using (u32 *)()[0], perf (lib/find_*_bit()) assumes it 
> gets
> lower 32bits of u64 which is wrong. Proposed fix is to swap the words
> of the u64 to handle this case. This is _not_ endianess swap.
> 
> Suggested-by: Yury Norov 
> Cc: Yury Norov 
> Cc: Peter Zijlstra 
> Cc: Ingo Molnar 
> Cc: Arnaldo Carvalho de Melo 
> Cc: Alexander Shishkin 
> Cc: Jiri Olsa 
> Cc: Adrian Hunter 
> Cc: Kan Liang 
> Cc: Wang Nan 
> Cc: Michael Ellerman 
> Signed-off-by: Madhavan Srinivasan 
> ---
> Changelog v3:
> 1)Moved the swap function to lib/bitmap.c
> 2)Added a macro for declaration
> 3)Added the comments
> 
> Changelog v2:
> 1)Moved the swap code to a common function
> 2)Added more comments in the code
> 
> Changelog v1:
> 1)updated commit message and patch subject
> 2)Add the fix to print_sample_iregs() in builtin-script.c
> 
>  tools/include/linux/bitmap.h |  5 +
>  tools/lib/bitmap.c   | 18 ++
>  tools/perf/builtin-script.c  |  4 +++-
>  tools/perf/util/session.c|  4 +++-
>  4 files changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
> index 28f5493da491..6be9a7ddcb03 100644
> --- a/tools/include/linux/bitmap.h
> +++ b/tools/include/linux/bitmap.h
> @@ -2,14 +2,19 @@
>  #define _PERF_BITOPS_H
>  
>  #include 
> +#include 
>  #include 
>  
>  #define DECLARE_BITMAP(name,bits) \
>   unsigned long name[BITS_TO_LONGS(bits)]
>  
> +#define DECLARE_U64_BITMAP(__name) \
> + unsigned long __name[sizeof(u64)/sizeof(unsigned long)]
> +
>  int __bitmap_weight(const unsigned long *bitmap, int bits);
>  void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
>const unsigned long *bitmap2, int bits);
> +void bitmap_from_u64(unsigned long *dst, u64 mask);
>  
>  #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 
> 1)))
>  
> diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c
> index 0a1adcfd..464a0cc63e6a 100644
> --- a/tools/lib/bitmap.c
> +++ b/tools/lib/bitmap.c
> @@ -29,3 +29,21 @@ void __bitmap_or(unsigned long *dst, const unsigned long 
> *bitmap1,
>   for (k = 0; k < nr; k++)
>   dst[k] = bitmap1[k] | bitmap2[k];
>  }
> +
> +/*
> + * bitmap_from_u64 - Check and swap words within u64.
> + *  @mask: source bitmap
> + *  @dst:  destination bitmap
> + *
> + * In 32 bit big endian userspace on a 64bit kernel, 'unsigned long' is 32 
> bits.
> + * When reading u64 using (u32 *)()[0] and (u32 *)()[1],
> + * we will get wrong value for the mask. That is "(u32 *)()[0]"
> + * gets upper 32 bits of u64, but perf may expect lower 32bits of u64.
> + */
> +void bitmap_from_u64(unsigned long *dst, u64 mask)
> +{
> + dst[0] = mask & ULONG_MAX;
> +
> + if (sizeof(mask) > sizeof(unsigned long))
> + dst[1] = mask >> 32;
> +}
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index e3ce2f34d3ad..1120ca117071 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -412,11 +412,13 @@ static void print_sample_iregs(struct perf_sample 
> *sample,
>   struct regs_dump *regs = >intr_regs;
>   uint64_t mask = attr->sample_regs_intr;
>   unsigned i = 0, r;
> + DECLARE_U64_BITMAP(_mask);

I thought again, and realized that it may be just
DECLARE_BITMAP(_mask, 64);

I think it's better than introduce new macro and I'd recommend you to
send v5 doing this. But this version is OK to me as well. So it's up
to you.

Reviewed-by: Yury Norov 

>   if (!regs)
>   return;
>  
> - for_each_set_bit(r, (unsigned long *) , sizeof(mask) * 8) {
> + bitmap_from_u64(_mask, mask);
> + for_each_set_bit(r, _mask, sizeof(mask) * 8) {
>   u64 val = regs->regs[i++];
>   printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
>   }
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 5214974e841a..fab1f9c1e0f5 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -940,8 +940,10 @@ static void branch_stack__printf(struct perf_sample 
> *sample)
>  static void regs_dump__printf(u64 mask, u64 *regs)
>  {
>   unsigned rid, i = 0;
> + 

Re: [PATCH v4] tools/perf: Fix the mask in regs_dump__printf and print_sample_iregs

2016-06-22 Thread Yury Norov
On Thu, Jun 23, 2016 at 10:31:16AM +0530, Madhavan Srinivasan wrote:
> When decoding the perf_regs mask in regs_dump__printf(),
> we loop through the mask using find_first_bit and find_next_bit functions.
> "mask" is of type "u64", but sent as a "unsigned long *" to
> lib functions along with sizeof().
> 
> While the exisitng code works fine in most of the case,
> the logic is broken when using a 32bit perf on a 64bit kernel (Big Endian).
> When reading u64 using (u32 *)()[0], perf (lib/find_*_bit()) assumes it 
> gets
> lower 32bits of u64 which is wrong. Proposed fix is to swap the words
> of the u64 to handle this case. This is _not_ endianess swap.
> 
> Suggested-by: Yury Norov 
> Cc: Yury Norov 
> Cc: Peter Zijlstra 
> Cc: Ingo Molnar 
> Cc: Arnaldo Carvalho de Melo 
> Cc: Alexander Shishkin 
> Cc: Jiri Olsa 
> Cc: Adrian Hunter 
> Cc: Kan Liang 
> Cc: Wang Nan 
> Cc: Michael Ellerman 
> Signed-off-by: Madhavan Srinivasan 
> ---
> Changelog v3:
> 1)Moved the swap function to lib/bitmap.c
> 2)Added a macro for declaration
> 3)Added the comments
> 
> Changelog v2:
> 1)Moved the swap code to a common function
> 2)Added more comments in the code
> 
> Changelog v1:
> 1)updated commit message and patch subject
> 2)Add the fix to print_sample_iregs() in builtin-script.c
> 
>  tools/include/linux/bitmap.h |  5 +
>  tools/lib/bitmap.c   | 18 ++
>  tools/perf/builtin-script.c  |  4 +++-
>  tools/perf/util/session.c|  4 +++-
>  4 files changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
> index 28f5493da491..6be9a7ddcb03 100644
> --- a/tools/include/linux/bitmap.h
> +++ b/tools/include/linux/bitmap.h
> @@ -2,14 +2,19 @@
>  #define _PERF_BITOPS_H
>  
>  #include 
> +#include 
>  #include 
>  
>  #define DECLARE_BITMAP(name,bits) \
>   unsigned long name[BITS_TO_LONGS(bits)]
>  
> +#define DECLARE_U64_BITMAP(__name) \
> + unsigned long __name[sizeof(u64)/sizeof(unsigned long)]
> +
>  int __bitmap_weight(const unsigned long *bitmap, int bits);
>  void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
>const unsigned long *bitmap2, int bits);
> +void bitmap_from_u64(unsigned long *dst, u64 mask);
>  
>  #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 
> 1)))
>  
> diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c
> index 0a1adcfd..464a0cc63e6a 100644
> --- a/tools/lib/bitmap.c
> +++ b/tools/lib/bitmap.c
> @@ -29,3 +29,21 @@ void __bitmap_or(unsigned long *dst, const unsigned long 
> *bitmap1,
>   for (k = 0; k < nr; k++)
>   dst[k] = bitmap1[k] | bitmap2[k];
>  }
> +
> +/*
> + * bitmap_from_u64 - Check and swap words within u64.
> + *  @mask: source bitmap
> + *  @dst:  destination bitmap
> + *
> + * In 32 bit big endian userspace on a 64bit kernel, 'unsigned long' is 32 
> bits.
> + * When reading u64 using (u32 *)()[0] and (u32 *)()[1],
> + * we will get wrong value for the mask. That is "(u32 *)()[0]"
> + * gets upper 32 bits of u64, but perf may expect lower 32bits of u64.
> + */
> +void bitmap_from_u64(unsigned long *dst, u64 mask)
> +{
> + dst[0] = mask & ULONG_MAX;
> +
> + if (sizeof(mask) > sizeof(unsigned long))
> + dst[1] = mask >> 32;
> +}
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index e3ce2f34d3ad..1120ca117071 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -412,11 +412,13 @@ static void print_sample_iregs(struct perf_sample 
> *sample,
>   struct regs_dump *regs = >intr_regs;
>   uint64_t mask = attr->sample_regs_intr;
>   unsigned i = 0, r;
> + DECLARE_U64_BITMAP(_mask);

I thought again, and realized that it may be just
DECLARE_BITMAP(_mask, 64);

I think it's better than introduce new macro and I'd recommend you to
send v5 doing this. But this version is OK to me as well. So it's up
to you.

Reviewed-by: Yury Norov 

>   if (!regs)
>   return;
>  
> - for_each_set_bit(r, (unsigned long *) , sizeof(mask) * 8) {
> + bitmap_from_u64(_mask, mask);
> + for_each_set_bit(r, _mask, sizeof(mask) * 8) {
>   u64 val = regs->regs[i++];
>   printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
>   }
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 5214974e841a..fab1f9c1e0f5 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -940,8 +940,10 @@ static void branch_stack__printf(struct perf_sample 
> *sample)
>  static void regs_dump__printf(u64 mask, u64 *regs)
>  {
>   unsigned rid, i = 0;
> + DECLARE_U64_BITMAP(_mask);
>  
> - for_each_set_bit(rid, (unsigned long *) , sizeof(mask) * 8) {
> + bitmap_from_u64(_mask, mask);
> + for_each_set_bit(rid, _mask, sizeof(mask) * 8) {
>   u64 val = regs[i++];
>  
>   printf(" %-5s 0x%" PRIx64 "\n",
> -- 
> 1.9.1


Re: [PATCH v4 2/2] dt-bindings: analogix_dp: rockchip: correct the wrong compatible name

2016-06-22 Thread Doug Anderson
Hi,

On Wed, Jun 22, 2016 at 6:47 PM, Yakir Yang  wrote:
> The document about rockchip platform make a mistaken in available
> compatible name of "rk3288-edp", we should correct it to "rk3288-dp"
> which correspond to the compatible name in driver.
>
> This mistaken was introduced in commit be91c36247089 ("dt-bindings:
> add document for rockchip variant of analogix_dp").
>
> Reported-by: Tomasz Figa 
> Signed-off-by: Yakir Yang 
> ---
> Hi all,
>
> This is an external patch for analogix_dp misc cleanup thread [0]
> [0]: https://patchwork.kernel.org/patch/9175613/
>
> BR,
> - Yakir
>
> Changes in v4: None
> Changes in v3:
> - Add this patch in v3
>
>  .../devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt   | 2 
> +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Douglas Anderson 


Re: [PATCH v4 2/2] dt-bindings: analogix_dp: rockchip: correct the wrong compatible name

2016-06-22 Thread Doug Anderson
Hi,

On Wed, Jun 22, 2016 at 6:47 PM, Yakir Yang  wrote:
> The document about rockchip platform make a mistaken in available
> compatible name of "rk3288-edp", we should correct it to "rk3288-dp"
> which correspond to the compatible name in driver.
>
> This mistaken was introduced in commit be91c36247089 ("dt-bindings:
> add document for rockchip variant of analogix_dp").
>
> Reported-by: Tomasz Figa 
> Signed-off-by: Yakir Yang 
> ---
> Hi all,
>
> This is an external patch for analogix_dp misc cleanup thread [0]
> [0]: https://patchwork.kernel.org/patch/9175613/
>
> BR,
> - Yakir
>
> Changes in v4: None
> Changes in v3:
> - Add this patch in v3
>
>  .../devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt   | 2 
> +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Douglas Anderson 


Re: [PATCH v4.1 1/2] drm/rockchip: analogix_dp: introduce the pclk for grf

2016-06-22 Thread Doug Anderson
Yakir,

On Wed, Jun 22, 2016 at 6:58 PM, Yakir Yang  wrote:
> For RK3399's GRF module, if we want to operate the graphic related grf
> registers, we need to enable the pclk_vio_grf which supply power for VIO
> GRF IOs, so it's better to introduce an optional grf clock in driver.
>
> Signed-off-by: Yakir Yang 
> ---
> Hi all,
>
> This is an external patch for analogix_dp misc cleanup thread [0]
> [0]: https://patchwork.kernel.org/patch/9175613/
>
> BR,
> - Yakir
>
> Changes in v4.1:
> - Fix compiled error, sorry.
>   "dp->cgfclk"  -->  'dp->grfclk'
>
> Changes in v4:
> - Check the the error code properly, 'EPROBE_DEFER' should be returned,
>   'ENOENT' should assign a NULL point to grfclk, other errors should be
>   regarded as failed. (Tomasz, Doug, reviewed at Google Gerrit)
> 
> [https://chromium-review.googlesource.com/#/c/351821/20/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c@249]
> - Add the document about optional 'grf' clock (Tomasz, Doug, reviewed at 
> Google Gerrit)
> [https://chromium-review.googlesource.com/#/c/351821/]
>
> Changes in v3:
> - Add this patch in v3
>
>  .../display/rockchip/analogix_dp-rockchip.txt  |  6 ++
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 23 
> +++---
>  2 files changed, 26 insertions(+), 3 deletions(-)

I probably would have split into two patches so the bindings was its
own patch, but I don't think it's strictly required.

In any case, this seems good to me.

Reviewed-by: Douglas Anderson 


Re: [PATCH v4.1 1/2] drm/rockchip: analogix_dp: introduce the pclk for grf

2016-06-22 Thread Doug Anderson
Yakir,

On Wed, Jun 22, 2016 at 6:58 PM, Yakir Yang  wrote:
> For RK3399's GRF module, if we want to operate the graphic related grf
> registers, we need to enable the pclk_vio_grf which supply power for VIO
> GRF IOs, so it's better to introduce an optional grf clock in driver.
>
> Signed-off-by: Yakir Yang 
> ---
> Hi all,
>
> This is an external patch for analogix_dp misc cleanup thread [0]
> [0]: https://patchwork.kernel.org/patch/9175613/
>
> BR,
> - Yakir
>
> Changes in v4.1:
> - Fix compiled error, sorry.
>   "dp->cgfclk"  -->  'dp->grfclk'
>
> Changes in v4:
> - Check the the error code properly, 'EPROBE_DEFER' should be returned,
>   'ENOENT' should assign a NULL point to grfclk, other errors should be
>   regarded as failed. (Tomasz, Doug, reviewed at Google Gerrit)
> 
> [https://chromium-review.googlesource.com/#/c/351821/20/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c@249]
> - Add the document about optional 'grf' clock (Tomasz, Doug, reviewed at 
> Google Gerrit)
> [https://chromium-review.googlesource.com/#/c/351821/]
>
> Changes in v3:
> - Add this patch in v3
>
>  .../display/rockchip/analogix_dp-rockchip.txt  |  6 ++
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 23 
> +++---
>  2 files changed, 26 insertions(+), 3 deletions(-)

I probably would have split into two patches so the bindings was its
own patch, but I don't think it's strictly required.

In any case, this seems good to me.

Reviewed-by: Douglas Anderson 


Re: [PATCH net-next V2] tun: introduce tx skb ring

2016-06-22 Thread Jason Wang



On 2016年06月23日 02:18, Michael S. Tsirkin wrote:

On Fri, Jun 17, 2016 at 03:41:20AM +0300, Michael S. Tsirkin wrote:

>Would it help to have ptr_ring_resize that gets an array of
>rings and resizes them both to same length?

OK, here it is. Untested so far, and no skb wrapper.
Pls let me know whether this is what you had in mind.


Exactly what I want.

Thanks


Re: [PATCH net-next V2] tun: introduce tx skb ring

2016-06-22 Thread Jason Wang



On 2016年06月23日 02:18, Michael S. Tsirkin wrote:

On Fri, Jun 17, 2016 at 03:41:20AM +0300, Michael S. Tsirkin wrote:

>Would it help to have ptr_ring_resize that gets an array of
>rings and resizes them both to same length?

OK, here it is. Untested so far, and no skb wrapper.
Pls let me know whether this is what you had in mind.


Exactly what I want.

Thanks


[PATCH] xen: fix upper bound of pmd loop in xen_cleanhighmap()

2016-06-22 Thread Juergen Gross
xen_cleanhighmap() is operating on level2_kernel_pgt only. The upper
bound of the loop setting non-kernel-image entries to zero should not
exceed the size of level2_kernel_pgt.

Reported-by: Linus Torvalds 
Signed-off-by: Juergen Gross 
---
 arch/x86/xen/mmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 478a2de..2693b7e 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1113,7 +1113,7 @@ static void __init xen_cleanhighmap(unsigned long vaddr,
 
/* NOTE: The loop is more greedy than the cleanup_highmap variant.
 * We include the PMD passed in on _both_ boundaries. */
-   for (; vaddr <= vaddr_end && (pmd < (level2_kernel_pgt + PAGE_SIZE));
+   for (; vaddr <= vaddr_end && (pmd < (level2_kernel_pgt + PTRS_PER_PMD));
pmd++, vaddr += PMD_SIZE) {
if (pmd_none(*pmd))
continue;
-- 
2.6.6



[PATCH] xen: fix upper bound of pmd loop in xen_cleanhighmap()

2016-06-22 Thread Juergen Gross
xen_cleanhighmap() is operating on level2_kernel_pgt only. The upper
bound of the loop setting non-kernel-image entries to zero should not
exceed the size of level2_kernel_pgt.

Reported-by: Linus Torvalds 
Signed-off-by: Juergen Gross 
---
 arch/x86/xen/mmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 478a2de..2693b7e 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1113,7 +1113,7 @@ static void __init xen_cleanhighmap(unsigned long vaddr,
 
/* NOTE: The loop is more greedy than the cleanup_highmap variant.
 * We include the PMD passed in on _both_ boundaries. */
-   for (; vaddr <= vaddr_end && (pmd < (level2_kernel_pgt + PAGE_SIZE));
+   for (; vaddr <= vaddr_end && (pmd < (level2_kernel_pgt + PTRS_PER_PMD));
pmd++, vaddr += PMD_SIZE) {
if (pmd_none(*pmd))
continue;
-- 
2.6.6



Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface

2016-06-22 Thread Stephan Mueller
Am Mittwoch, 22. Juni 2016, 15:45:38 schrieb Mat Martineau:

Hi Mat,

> > 
> > Ok, I'll update the patch.
> 
> Thanks, that helps (especially with pkcs1pad).

Tadeusz received the updated patch from me to integrate it into his patch set.
> 
> This brings me to another proposal for read buffer sizing: AF_ALG akcipher
> can guarantee that partial reads (where the read buffer is shorter than
> the output of the crypto op) will work using the same semantics as
> SOCK_DGRAM/SOCK_SEQPACKET. With those sockets, as much data as will fit is
> copied in to the read buffer and the remainder is discarded.
> 
> I realize there's a performance and memory tradeoff, since the crypto
> algorithm needs a sufficiently large output buffer that would have to be
> created by AF_ALG akcipher. The user could manage that tradeoff by
> providing a larger buffer (typically key_size?) if it wants to avoid
> allocating and copying intermediate buffers inside the kernel.

How shall the user know that something got truncated or that the kernel 
created memory?

Ciao
Stephan


Re: [PATCH 01/27] [AARCH64] Fix utmp struct for compatibility reasons.

2016-06-22 Thread Andrew Pinski
On Wed, Jun 22, 2016 at 9:35 PM, Yury Norov  wrote:
> On Tue, Jun 21, 2016 at 11:14:54AM +0100, Szabolcs Nagy wrote:
>> On 21/06/16 06:06, Yury Norov wrote:
>> > From: Andrew Pinski 
>> >
>> > NOTE This is an ABI change for AARCH64.
>> > If you have some AARCH32 and AARCH64 applications and they both use
>> > utmp, one of them will fail due to the use of time_t inside the
>> > utmp binary format.
>> >
>> > This fixes the problem by setting __WORDSIZE_TIME64_COMPAT32.
>>
>> i think changing the abi now is not ok.
>>
>> this is BZ 17470 and i think it should be discussed separately
>> from ilp32.
>>
>> if it's possible to detect the utmp file format, that would
>> allow a reasonable fix, the way glibc changes the struct def
>> based on lp64 targets is non-conforming.
>
> Hi Joseph, Szabolcs,
>
> I revised it and found that we don't need __WORDSIZE_TIME64_COMPAT32
> because ilp32 already has 32-bit time_t.
> So for now sysdeps/aarch64/bits/wordsize.h is looking like this:
> #ifdef __LP64__
> # define __WORDSIZE64
> #else
> # define __WORDSIZE32
> # define __WORDSIZE32_SIZE_ULONG   1
> # define __WORDSIZE32_PTRDIFF_LONG 1
> #endif
>
> is it OK? Andrew?


The problem right now is utmp struct is incompatible between ILP32 and
LP64 (even incompatible between AARCH32 and AARCH64).  So right now if
you have two programs which use the utmp file (one aarch64 and one
which is aarch32 or one which is ILP32), one which writes the data
will not able to read the other one.

So if you want aarch64 to be compatible with aarch32, you need to
define __WORDSIZE_TIME64_COMPAT32.  If we don't want aarch64 and
aarch32 to be compatible at all, then we can drop this patch or if you
don't want LP64 and ILP32 to be compatible either.

So the question now comes do we break AARCH32 or AARCH64 or do we go
one step further and fix detecting of which version of the utmp is
stored on disk and use that.
So we are going to need to the further step for 64bit time_t issues on
32bit ABIs.  So do we worry about this now or wait for the rest of the
time_t work?

Thanks,
Andrew


Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface

2016-06-22 Thread Stephan Mueller
Am Mittwoch, 22. Juni 2016, 15:45:38 schrieb Mat Martineau:

Hi Mat,

> > 
> > Ok, I'll update the patch.
> 
> Thanks, that helps (especially with pkcs1pad).

Tadeusz received the updated patch from me to integrate it into his patch set.
> 
> This brings me to another proposal for read buffer sizing: AF_ALG akcipher
> can guarantee that partial reads (where the read buffer is shorter than
> the output of the crypto op) will work using the same semantics as
> SOCK_DGRAM/SOCK_SEQPACKET. With those sockets, as much data as will fit is
> copied in to the read buffer and the remainder is discarded.
> 
> I realize there's a performance and memory tradeoff, since the crypto
> algorithm needs a sufficiently large output buffer that would have to be
> created by AF_ALG akcipher. The user could manage that tradeoff by
> providing a larger buffer (typically key_size?) if it wants to avoid
> allocating and copying intermediate buffers inside the kernel.

How shall the user know that something got truncated or that the kernel 
created memory?

Ciao
Stephan


Re: [PATCH 01/27] [AARCH64] Fix utmp struct for compatibility reasons.

2016-06-22 Thread Andrew Pinski
On Wed, Jun 22, 2016 at 9:35 PM, Yury Norov  wrote:
> On Tue, Jun 21, 2016 at 11:14:54AM +0100, Szabolcs Nagy wrote:
>> On 21/06/16 06:06, Yury Norov wrote:
>> > From: Andrew Pinski 
>> >
>> > NOTE This is an ABI change for AARCH64.
>> > If you have some AARCH32 and AARCH64 applications and they both use
>> > utmp, one of them will fail due to the use of time_t inside the
>> > utmp binary format.
>> >
>> > This fixes the problem by setting __WORDSIZE_TIME64_COMPAT32.
>>
>> i think changing the abi now is not ok.
>>
>> this is BZ 17470 and i think it should be discussed separately
>> from ilp32.
>>
>> if it's possible to detect the utmp file format, that would
>> allow a reasonable fix, the way glibc changes the struct def
>> based on lp64 targets is non-conforming.
>
> Hi Joseph, Szabolcs,
>
> I revised it and found that we don't need __WORDSIZE_TIME64_COMPAT32
> because ilp32 already has 32-bit time_t.
> So for now sysdeps/aarch64/bits/wordsize.h is looking like this:
> #ifdef __LP64__
> # define __WORDSIZE64
> #else
> # define __WORDSIZE32
> # define __WORDSIZE32_SIZE_ULONG   1
> # define __WORDSIZE32_PTRDIFF_LONG 1
> #endif
>
> is it OK? Andrew?


The problem right now is utmp struct is incompatible between ILP32 and
LP64 (even incompatible between AARCH32 and AARCH64).  So right now if
you have two programs which use the utmp file (one aarch64 and one
which is aarch32 or one which is ILP32), one which writes the data
will not able to read the other one.

So if you want aarch64 to be compatible with aarch32, you need to
define __WORDSIZE_TIME64_COMPAT32.  If we don't want aarch64 and
aarch32 to be compatible at all, then we can drop this patch or if you
don't want LP64 and ILP32 to be compatible either.

So the question now comes do we break AARCH32 or AARCH64 or do we go
one step further and fix detecting of which version of the utmp is
stored on disk and use that.
So we are going to need to the further step for 64bit time_t issues on
32bit ABIs.  So do we worry about this now or wait for the rest of the
time_t work?

Thanks,
Andrew


Re: [PATCH v2 0/2] Correct iTCO Watchdog for Apollo Lake

2016-06-22 Thread Darren Hart
On Tue, Jun 21, 2016 at 11:01:01PM -0700, Guenter Roeck wrote:
> On 06/21/2016 09:53 PM, Yong, Jonathan wrote:
> > On 06/17/2016 08:36, Yong, Jonathan wrote:
> > > These patches fix the iTCO watchdog for Apollo Lake.
> > > I changed the watchdog memory io to only use 4 bytes rather
> > > the whole region, I'm not sure if that is the correct way.
> > > 
> > > The previous 0x30h offset in intel_pmc_ipc.c was for based
> > > on the earlier BXT-M platform. Apollo Lake has it at 0x40h.
> > > 
> > > Let me know if the patches need changes.
> > > Please CC me as I am not subscribed, thanks.
> > > 
> > > * Resent, typo in linux-kernel email address
> > > 
> > > Changes since v1:
> > > * Watchdog NO_REBOOT bit off-by-one corrected.
> > > 
> > > Yong, Jonathan (2):
> > >watchdog: iTCO-wdt handle 5th variation for Apollo Lake
> > >x86: Fix Apollo Lake Watchdog address in PMC driver
> > > 
> > >   drivers/platform/x86/intel_pmc_ipc.c | 10 ++
> > >   drivers/watchdog/iTCO_wdt.c  |  2 ++
> > >   2 files changed, 8 insertions(+), 4 deletions(-)
> > > 
> > 
> > Ping.
> > 
> > 
> Waiting for an Ack from Darren.

Jonathan verified that the change will not break existing external platforms.
I'm happy with it from that perspective.

Guenter, will you take both patches together?

Reviewed-by: Darren Hart 


-- 
Darren Hart
Intel Open Source Technology Center


Re: [PATCH v2 0/2] Correct iTCO Watchdog for Apollo Lake

2016-06-22 Thread Darren Hart
On Tue, Jun 21, 2016 at 11:01:01PM -0700, Guenter Roeck wrote:
> On 06/21/2016 09:53 PM, Yong, Jonathan wrote:
> > On 06/17/2016 08:36, Yong, Jonathan wrote:
> > > These patches fix the iTCO watchdog for Apollo Lake.
> > > I changed the watchdog memory io to only use 4 bytes rather
> > > the whole region, I'm not sure if that is the correct way.
> > > 
> > > The previous 0x30h offset in intel_pmc_ipc.c was for based
> > > on the earlier BXT-M platform. Apollo Lake has it at 0x40h.
> > > 
> > > Let me know if the patches need changes.
> > > Please CC me as I am not subscribed, thanks.
> > > 
> > > * Resent, typo in linux-kernel email address
> > > 
> > > Changes since v1:
> > > * Watchdog NO_REBOOT bit off-by-one corrected.
> > > 
> > > Yong, Jonathan (2):
> > >watchdog: iTCO-wdt handle 5th variation for Apollo Lake
> > >x86: Fix Apollo Lake Watchdog address in PMC driver
> > > 
> > >   drivers/platform/x86/intel_pmc_ipc.c | 10 ++
> > >   drivers/watchdog/iTCO_wdt.c  |  2 ++
> > >   2 files changed, 8 insertions(+), 4 deletions(-)
> > > 
> > 
> > Ping.
> > 
> > 
> Waiting for an Ack from Darren.

Jonathan verified that the change will not break existing external platforms.
I'm happy with it from that perspective.

Guenter, will you take both patches together?

Reviewed-by: Darren Hart 


-- 
Darren Hart
Intel Open Source Technology Center


[PATCH v4] tools/perf: Fix the mask in regs_dump__printf and print_sample_iregs

2016-06-22 Thread Madhavan Srinivasan
When decoding the perf_regs mask in regs_dump__printf(),
we loop through the mask using find_first_bit and find_next_bit functions.
"mask" is of type "u64", but sent as a "unsigned long *" to
lib functions along with sizeof().

While the exisitng code works fine in most of the case,
the logic is broken when using a 32bit perf on a 64bit kernel (Big Endian).
When reading u64 using (u32 *)()[0], perf (lib/find_*_bit()) assumes it gets
lower 32bits of u64 which is wrong. Proposed fix is to swap the words
of the u64 to handle this case. This is _not_ endianess swap.

Suggested-by: Yury Norov 
Cc: Yury Norov 
Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexander Shishkin 
Cc: Jiri Olsa 
Cc: Adrian Hunter 
Cc: Kan Liang 
Cc: Wang Nan 
Cc: Michael Ellerman 
Signed-off-by: Madhavan Srinivasan 
---
Changelog v3:
1)Moved the swap function to lib/bitmap.c
2)Added a macro for declaration
3)Added the comments

Changelog v2:
1)Moved the swap code to a common function
2)Added more comments in the code

Changelog v1:
1)updated commit message and patch subject
2)Add the fix to print_sample_iregs() in builtin-script.c

 tools/include/linux/bitmap.h |  5 +
 tools/lib/bitmap.c   | 18 ++
 tools/perf/builtin-script.c  |  4 +++-
 tools/perf/util/session.c|  4 +++-
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
index 28f5493da491..6be9a7ddcb03 100644
--- a/tools/include/linux/bitmap.h
+++ b/tools/include/linux/bitmap.h
@@ -2,14 +2,19 @@
 #define _PERF_BITOPS_H
 
 #include 
+#include 
 #include 
 
 #define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
 
+#define DECLARE_U64_BITMAP(__name) \
+   unsigned long __name[sizeof(u64)/sizeof(unsigned long)]
+
 int __bitmap_weight(const unsigned long *bitmap, int bits);
 void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
 const unsigned long *bitmap2, int bits);
+void bitmap_from_u64(unsigned long *dst, u64 mask);
 
 #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
 
diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c
index 0a1adcfd..464a0cc63e6a 100644
--- a/tools/lib/bitmap.c
+++ b/tools/lib/bitmap.c
@@ -29,3 +29,21 @@ void __bitmap_or(unsigned long *dst, const unsigned long 
*bitmap1,
for (k = 0; k < nr; k++)
dst[k] = bitmap1[k] | bitmap2[k];
 }
+
+/*
+ * bitmap_from_u64 - Check and swap words within u64.
+ *  @mask: source bitmap
+ *  @dst:  destination bitmap
+ *
+ * In 32 bit big endian userspace on a 64bit kernel, 'unsigned long' is 32 
bits.
+ * When reading u64 using (u32 *)()[0] and (u32 *)()[1],
+ * we will get wrong value for the mask. That is "(u32 *)()[0]"
+ * gets upper 32 bits of u64, but perf may expect lower 32bits of u64.
+ */
+void bitmap_from_u64(unsigned long *dst, u64 mask)
+{
+   dst[0] = mask & ULONG_MAX;
+
+   if (sizeof(mask) > sizeof(unsigned long))
+   dst[1] = mask >> 32;
+}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index e3ce2f34d3ad..1120ca117071 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -412,11 +412,13 @@ static void print_sample_iregs(struct perf_sample *sample,
struct regs_dump *regs = >intr_regs;
uint64_t mask = attr->sample_regs_intr;
unsigned i = 0, r;
+   DECLARE_U64_BITMAP(_mask);
 
if (!regs)
return;
 
-   for_each_set_bit(r, (unsigned long *) , sizeof(mask) * 8) {
+   bitmap_from_u64(_mask, mask);
+   for_each_set_bit(r, _mask, sizeof(mask) * 8) {
u64 val = regs->regs[i++];
printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 5214974e841a..fab1f9c1e0f5 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -940,8 +940,10 @@ static void branch_stack__printf(struct perf_sample 
*sample)
 static void regs_dump__printf(u64 mask, u64 *regs)
 {
unsigned rid, i = 0;
+   DECLARE_U64_BITMAP(_mask);
 
-   for_each_set_bit(rid, (unsigned long *) , sizeof(mask) * 8) {
+   bitmap_from_u64(_mask, mask);
+   for_each_set_bit(rid, _mask, sizeof(mask) * 8) {
u64 val = regs[i++];
 
printf(" %-5s 0x%" PRIx64 "\n",
-- 
1.9.1



[PATCH v4] tools/perf: Fix the mask in regs_dump__printf and print_sample_iregs

2016-06-22 Thread Madhavan Srinivasan
When decoding the perf_regs mask in regs_dump__printf(),
we loop through the mask using find_first_bit and find_next_bit functions.
"mask" is of type "u64", but sent as a "unsigned long *" to
lib functions along with sizeof().

While the exisitng code works fine in most of the case,
the logic is broken when using a 32bit perf on a 64bit kernel (Big Endian).
When reading u64 using (u32 *)()[0], perf (lib/find_*_bit()) assumes it gets
lower 32bits of u64 which is wrong. Proposed fix is to swap the words
of the u64 to handle this case. This is _not_ endianess swap.

Suggested-by: Yury Norov 
Cc: Yury Norov 
Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexander Shishkin 
Cc: Jiri Olsa 
Cc: Adrian Hunter 
Cc: Kan Liang 
Cc: Wang Nan 
Cc: Michael Ellerman 
Signed-off-by: Madhavan Srinivasan 
---
Changelog v3:
1)Moved the swap function to lib/bitmap.c
2)Added a macro for declaration
3)Added the comments

Changelog v2:
1)Moved the swap code to a common function
2)Added more comments in the code

Changelog v1:
1)updated commit message and patch subject
2)Add the fix to print_sample_iregs() in builtin-script.c

 tools/include/linux/bitmap.h |  5 +
 tools/lib/bitmap.c   | 18 ++
 tools/perf/builtin-script.c  |  4 +++-
 tools/perf/util/session.c|  4 +++-
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
index 28f5493da491..6be9a7ddcb03 100644
--- a/tools/include/linux/bitmap.h
+++ b/tools/include/linux/bitmap.h
@@ -2,14 +2,19 @@
 #define _PERF_BITOPS_H
 
 #include 
+#include 
 #include 
 
 #define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
 
+#define DECLARE_U64_BITMAP(__name) \
+   unsigned long __name[sizeof(u64)/sizeof(unsigned long)]
+
 int __bitmap_weight(const unsigned long *bitmap, int bits);
 void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
 const unsigned long *bitmap2, int bits);
+void bitmap_from_u64(unsigned long *dst, u64 mask);
 
 #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
 
diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c
index 0a1adcfd..464a0cc63e6a 100644
--- a/tools/lib/bitmap.c
+++ b/tools/lib/bitmap.c
@@ -29,3 +29,21 @@ void __bitmap_or(unsigned long *dst, const unsigned long 
*bitmap1,
for (k = 0; k < nr; k++)
dst[k] = bitmap1[k] | bitmap2[k];
 }
+
+/*
+ * bitmap_from_u64 - Check and swap words within u64.
+ *  @mask: source bitmap
+ *  @dst:  destination bitmap
+ *
+ * In 32 bit big endian userspace on a 64bit kernel, 'unsigned long' is 32 
bits.
+ * When reading u64 using (u32 *)()[0] and (u32 *)()[1],
+ * we will get wrong value for the mask. That is "(u32 *)()[0]"
+ * gets upper 32 bits of u64, but perf may expect lower 32bits of u64.
+ */
+void bitmap_from_u64(unsigned long *dst, u64 mask)
+{
+   dst[0] = mask & ULONG_MAX;
+
+   if (sizeof(mask) > sizeof(unsigned long))
+   dst[1] = mask >> 32;
+}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index e3ce2f34d3ad..1120ca117071 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -412,11 +412,13 @@ static void print_sample_iregs(struct perf_sample *sample,
struct regs_dump *regs = >intr_regs;
uint64_t mask = attr->sample_regs_intr;
unsigned i = 0, r;
+   DECLARE_U64_BITMAP(_mask);
 
if (!regs)
return;
 
-   for_each_set_bit(r, (unsigned long *) , sizeof(mask) * 8) {
+   bitmap_from_u64(_mask, mask);
+   for_each_set_bit(r, _mask, sizeof(mask) * 8) {
u64 val = regs->regs[i++];
printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 5214974e841a..fab1f9c1e0f5 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -940,8 +940,10 @@ static void branch_stack__printf(struct perf_sample 
*sample)
 static void regs_dump__printf(u64 mask, u64 *regs)
 {
unsigned rid, i = 0;
+   DECLARE_U64_BITMAP(_mask);
 
-   for_each_set_bit(rid, (unsigned long *) , sizeof(mask) * 8) {
+   bitmap_from_u64(_mask, mask);
+   for_each_set_bit(rid, _mask, sizeof(mask) * 8) {
u64 val = regs[i++];
 
printf(" %-5s 0x%" PRIx64 "\n",
-- 
1.9.1



[PATCH] i40e: Remove redundant memset

2016-06-22 Thread Amitoj Kaur Chawla
Remove redundant call to memset before a call to memcpy.

The Coccinelle semantic patch used to make this change is as follows:
@@
expression e1,e2,e3,e4;
@@

- memset(e1,e2,e3);
  memcpy(e1,e4,e3);

Signed-off-by: Amitoj Kaur Chawla 
---
 drivers/net/ethernet/intel/i40e/i40e_main.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c 
b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 3449129..45c1671 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7961,7 +7961,6 @@ static int i40e_config_rss_aq(struct i40e_vsi *vsi, const 
u8 *seed,
u8 *rss_lut;
int ret, i;
 
-   memset(_key, 0, sizeof(rss_key));
memcpy(_key, seed, sizeof(rss_key));
 
rss_lut = kzalloc(pf->rss_table_size, GFP_KERNEL);
-- 
1.9.1



[PATCH] i40e: Remove redundant memset

2016-06-22 Thread Amitoj Kaur Chawla
Remove redundant call to memset before a call to memcpy.

The Coccinelle semantic patch used to make this change is as follows:
@@
expression e1,e2,e3,e4;
@@

- memset(e1,e2,e3);
  memcpy(e1,e4,e3);

Signed-off-by: Amitoj Kaur Chawla 
---
 drivers/net/ethernet/intel/i40e/i40e_main.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c 
b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 3449129..45c1671 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7961,7 +7961,6 @@ static int i40e_config_rss_aq(struct i40e_vsi *vsi, const 
u8 *seed,
u8 *rss_lut;
int ret, i;
 
-   memset(_key, 0, sizeof(rss_key));
memcpy(_key, seed, sizeof(rss_key));
 
rss_lut = kzalloc(pf->rss_table_size, GFP_KERNEL);
-- 
1.9.1



[PATCH 1/2] Bluetooth: Add LED triggers for HCI frames tx and rx

2016-06-22 Thread Guodong Xu
Two LED triggers are defined: tx_led and rx_led. Upon frames
available in HCI core layer, for tx or for rx, the combined LED
can blink.

Verified on HiKey, 96boards. It uses hi6220 SoC and TI WL1835 combo
chip.

Signed-off-by: Guodong Xu 
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c |  3 +++
 net/bluetooth/leds.c | 15 +++
 net/bluetooth/leds.h |  2 ++
 4 files changed, 21 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index dc71473..37b8dd9 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -398,6 +398,7 @@ struct hci_dev {
bdaddr_trpa;
 
struct led_trigger  *power_led;
+   struct led_trigger  *tx_led, *rx_led;
 
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 45a9fc6..c6e1210 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3248,6 +3248,7 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff 
*skb)
skb_queue_tail(>rx_q, skb);
queue_work(hdev->workqueue, >rx_work);
 
+   hci_leds_blink_oneshot(hdev->rx_led);
return 0;
 }
 EXPORT_SYMBOL(hci_recv_frame);
@@ -3325,6 +3326,8 @@ static void hci_send_frame(struct hci_dev *hdev, struct 
sk_buff *skb)
BT_ERR("%s sending frame failed (%d)", hdev->name, err);
kfree_skb(skb);
}
+
+   hci_leds_blink_oneshot(hdev->tx_led);
 }
 
 /* Send HCI command */
diff --git a/net/bluetooth/leds.c b/net/bluetooth/leds.c
index 8319c84..c4825d5 100644
--- a/net/bluetooth/leds.c
+++ b/net/bluetooth/leds.c
@@ -19,6 +19,8 @@ struct hci_basic_led_trigger {
 #define to_hci_basic_led_trigger(arg) container_of(arg, \
struct hci_basic_led_trigger, led_trigger)
 
+#define BLUETOOTH_BLINK_DELAY  50 /* ms */
+
 void hci_leds_update_powered(struct hci_dev *hdev, bool enabled)
 {
if (hdev->power_led)
@@ -37,6 +39,15 @@ static void power_activate(struct led_classdev *led_cdev)
led_trigger_event(led_cdev->trigger, powered ? LED_FULL : LED_OFF);
 }
 
+void hci_leds_blink_oneshot(struct led_trigger *trig)
+{
+   unsigned long led_delay = BLUETOOTH_BLINK_DELAY;
+
+   if (!trig)
+   return;
+   led_trigger_blink_oneshot(trig, _delay, _delay, 0);
+}
+
 static struct led_trigger *led_allocate_basic(struct hci_dev *hdev,
void (*activate)(struct led_classdev *led_cdev),
const char *name)
@@ -71,4 +82,8 @@ void hci_leds_init(struct hci_dev *hdev)
 {
/* initialize power_led */
hdev->power_led = led_allocate_basic(hdev, power_activate, "power");
+   /* initialize tx_led */
+   hdev->tx_led = led_allocate_basic(hdev, NULL, "tx");
+   /* initialize rx_led */
+   hdev->rx_led = led_allocate_basic(hdev, NULL, "rx");
 }
diff --git a/net/bluetooth/leds.h b/net/bluetooth/leds.h
index a9c4d6e..9b1cccd 100644
--- a/net/bluetooth/leds.h
+++ b/net/bluetooth/leds.h
@@ -9,8 +9,10 @@
 #if IS_ENABLED(CONFIG_BT_LEDS)
 void hci_leds_update_powered(struct hci_dev *hdev, bool enabled);
 void hci_leds_init(struct hci_dev *hdev);
+void hci_leds_blink_oneshot(struct led_trigger *trig);
 #else
 static inline void hci_leds_update_powered(struct hci_dev *hdev,
   bool enabled) {}
 static inline void hci_leds_init(struct hci_dev *hdev) {}
+static inline void hci_leds_blink_oneshot(struct led_trigger *trig) {}
 #endif
-- 
1.9.1



[PATCH 2/2] arm64: dts: hikey: set bluetooth led trigger

2016-06-22 Thread Guodong Xu
Set bluetooth led trigger to hci0-rx, and so LED blinks on hci
frame receiving.

Signed-off-by: Guodong Xu 
---
 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts 
b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index e92a30c..5032792 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -132,7 +132,7 @@
bt_active_led {
label = "bt_active";
gpios = < 7 0>; /* <_bt_active_led>; */
-   linux,default-trigger = "hci0rx";
+   linux,default-trigger = "hci0-rx";
default-state = "off";
};
};
-- 
1.9.1



[PATCH 1/2] Bluetooth: Add LED triggers for HCI frames tx and rx

2016-06-22 Thread Guodong Xu
Two LED triggers are defined: tx_led and rx_led. Upon frames
available in HCI core layer, for tx or for rx, the combined LED
can blink.

Verified on HiKey, 96boards. It uses hi6220 SoC and TI WL1835 combo
chip.

Signed-off-by: Guodong Xu 
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c |  3 +++
 net/bluetooth/leds.c | 15 +++
 net/bluetooth/leds.h |  2 ++
 4 files changed, 21 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index dc71473..37b8dd9 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -398,6 +398,7 @@ struct hci_dev {
bdaddr_trpa;
 
struct led_trigger  *power_led;
+   struct led_trigger  *tx_led, *rx_led;
 
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 45a9fc6..c6e1210 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3248,6 +3248,7 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff 
*skb)
skb_queue_tail(>rx_q, skb);
queue_work(hdev->workqueue, >rx_work);
 
+   hci_leds_blink_oneshot(hdev->rx_led);
return 0;
 }
 EXPORT_SYMBOL(hci_recv_frame);
@@ -3325,6 +3326,8 @@ static void hci_send_frame(struct hci_dev *hdev, struct 
sk_buff *skb)
BT_ERR("%s sending frame failed (%d)", hdev->name, err);
kfree_skb(skb);
}
+
+   hci_leds_blink_oneshot(hdev->tx_led);
 }
 
 /* Send HCI command */
diff --git a/net/bluetooth/leds.c b/net/bluetooth/leds.c
index 8319c84..c4825d5 100644
--- a/net/bluetooth/leds.c
+++ b/net/bluetooth/leds.c
@@ -19,6 +19,8 @@ struct hci_basic_led_trigger {
 #define to_hci_basic_led_trigger(arg) container_of(arg, \
struct hci_basic_led_trigger, led_trigger)
 
+#define BLUETOOTH_BLINK_DELAY  50 /* ms */
+
 void hci_leds_update_powered(struct hci_dev *hdev, bool enabled)
 {
if (hdev->power_led)
@@ -37,6 +39,15 @@ static void power_activate(struct led_classdev *led_cdev)
led_trigger_event(led_cdev->trigger, powered ? LED_FULL : LED_OFF);
 }
 
+void hci_leds_blink_oneshot(struct led_trigger *trig)
+{
+   unsigned long led_delay = BLUETOOTH_BLINK_DELAY;
+
+   if (!trig)
+   return;
+   led_trigger_blink_oneshot(trig, _delay, _delay, 0);
+}
+
 static struct led_trigger *led_allocate_basic(struct hci_dev *hdev,
void (*activate)(struct led_classdev *led_cdev),
const char *name)
@@ -71,4 +82,8 @@ void hci_leds_init(struct hci_dev *hdev)
 {
/* initialize power_led */
hdev->power_led = led_allocate_basic(hdev, power_activate, "power");
+   /* initialize tx_led */
+   hdev->tx_led = led_allocate_basic(hdev, NULL, "tx");
+   /* initialize rx_led */
+   hdev->rx_led = led_allocate_basic(hdev, NULL, "rx");
 }
diff --git a/net/bluetooth/leds.h b/net/bluetooth/leds.h
index a9c4d6e..9b1cccd 100644
--- a/net/bluetooth/leds.h
+++ b/net/bluetooth/leds.h
@@ -9,8 +9,10 @@
 #if IS_ENABLED(CONFIG_BT_LEDS)
 void hci_leds_update_powered(struct hci_dev *hdev, bool enabled);
 void hci_leds_init(struct hci_dev *hdev);
+void hci_leds_blink_oneshot(struct led_trigger *trig);
 #else
 static inline void hci_leds_update_powered(struct hci_dev *hdev,
   bool enabled) {}
 static inline void hci_leds_init(struct hci_dev *hdev) {}
+static inline void hci_leds_blink_oneshot(struct led_trigger *trig) {}
 #endif
-- 
1.9.1



[PATCH 2/2] arm64: dts: hikey: set bluetooth led trigger

2016-06-22 Thread Guodong Xu
Set bluetooth led trigger to hci0-rx, and so LED blinks on hci
frame receiving.

Signed-off-by: Guodong Xu 
---
 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts 
b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index e92a30c..5032792 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -132,7 +132,7 @@
bt_active_led {
label = "bt_active";
gpios = < 7 0>; /* <_bt_active_led>; */
-   linux,default-trigger = "hci0rx";
+   linux,default-trigger = "hci0-rx";
default-state = "off";
};
};
-- 
1.9.1



Re: [PATCH 19/27] [AARCH64] Add typesizes.h for ILP32

2016-06-22 Thread Yury Norov
On Tue, Jun 21, 2016 at 07:59:27PM +0800, Zhangjian (Bamvor) wrote:
> Hi,
> 
> On 2016/6/21 15:58, Andreas Schwab wrote:
> >Yury Norov  writes:
> >
> >>diff --git a/sysdeps/unix/sysv/linux/sysdep-vdso.h 
> >>b/sysdeps/unix/sysv/linux/sysdep-vdso.h
> >>index e8c4a7b..351d6bb 100644
> >>--- a/sysdeps/unix/sysv/linux/sysdep-vdso.h
> >>+++ b/sysdeps/unix/sysv/linux/sysdep-vdso.h
> >>@@ -37,7 +37,7 @@
> >>  __label__ out;
> >>   \
> >>  __label__ iserr;  
> >>   \
> >>  INTERNAL_SYSCALL_DECL (sc_err);   
> >>   \
> >>-long int sc_ret;   
> >>  \
> >>+__syscall_slong_t sc_ret;  
> >>  \
> >>  \
> >>  __typeof (__vdso_##name) vdsop = __vdso_##name;   
> >>   \
> >>  PTR_DEMANGLE (vdsop);   \
> >>@@ -64,7 +64,7 @@
> >>  #  define INTERNAL_VSYSCALL(name, err, nr, args...)   
> >>   \
> >>({  
> >>   \
> >>  __label__ out;
> >>   \
> >>-long v_ret;
> >>  \
> >>+__syscall_slong_t v_ret;   
> >>  \
> >>  \
> >>  __typeof (__vdso_##name) vdsop = __vdso_##name;   
> >>   \
> >>  PTR_DEMANGLE (vdsop);   \
> >
> >That part should have no effect now that __SYSCALL_SLONG_TYPE remains to
> >be long.
> Agree. According to the discussion in "[PATCH 11/27] [AARCH64] Syscalls for 
> ILP32 are passed
> always via 64bit values.". We should update this to long long too.
> 

I think comment to patch 11 is outdated. Andreas right, this chunk is
useless. I'll remove it in next submission.


Re: [PATCH 19/27] [AARCH64] Add typesizes.h for ILP32

2016-06-22 Thread Yury Norov
On Tue, Jun 21, 2016 at 07:59:27PM +0800, Zhangjian (Bamvor) wrote:
> Hi,
> 
> On 2016/6/21 15:58, Andreas Schwab wrote:
> >Yury Norov  writes:
> >
> >>diff --git a/sysdeps/unix/sysv/linux/sysdep-vdso.h 
> >>b/sysdeps/unix/sysv/linux/sysdep-vdso.h
> >>index e8c4a7b..351d6bb 100644
> >>--- a/sysdeps/unix/sysv/linux/sysdep-vdso.h
> >>+++ b/sysdeps/unix/sysv/linux/sysdep-vdso.h
> >>@@ -37,7 +37,7 @@
> >>  __label__ out;
> >>   \
> >>  __label__ iserr;  
> >>   \
> >>  INTERNAL_SYSCALL_DECL (sc_err);   
> >>   \
> >>-long int sc_ret;   
> >>  \
> >>+__syscall_slong_t sc_ret;  
> >>  \
> >>  \
> >>  __typeof (__vdso_##name) vdsop = __vdso_##name;   
> >>   \
> >>  PTR_DEMANGLE (vdsop);   \
> >>@@ -64,7 +64,7 @@
> >>  #  define INTERNAL_VSYSCALL(name, err, nr, args...)   
> >>   \
> >>({  
> >>   \
> >>  __label__ out;
> >>   \
> >>-long v_ret;
> >>  \
> >>+__syscall_slong_t v_ret;   
> >>  \
> >>  \
> >>  __typeof (__vdso_##name) vdsop = __vdso_##name;   
> >>   \
> >>  PTR_DEMANGLE (vdsop);   \
> >
> >That part should have no effect now that __SYSCALL_SLONG_TYPE remains to
> >be long.
> Agree. According to the discussion in "[PATCH 11/27] [AARCH64] Syscalls for 
> ILP32 are passed
> always via 64bit values.". We should update this to long long too.
> 

I think comment to patch 11 is outdated. Andreas right, this chunk is
useless. I'll remove it in next submission.


Re: [PATCH 3.14 00/29] 3.14.73-stable review -rc2

2016-06-22 Thread Greg Kroah-Hartman
-rc2!

Please test this...

This is the start of the stable review cycle for the 3.14.73 release.
There are 35 patches in this series, all will be posted as a response
to this one.  If anyone has any issues with these being applied, please
let me know.

Responses should be made by Sat Jun 25 04:50:44 UTC 2016.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.14.73-rc2.gz
or in the git tree and branch at:
  git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
linux-3.14.y
and the diffstat can be found below.

thanks,

greg k-h

-
Pseudo-Shortlog of commits:

Greg Kroah-Hartman 
Linux 3.14.73-rc2

Florian Westphal 
netfilter: x_tables: do compat validation via translate_table

Dave Jones 
netfilter: ensure number of counters is >0 in do_replace()

Florian Westphal 
netfilter: x_tables: xt_compat_match_from_user doesn't need a retval

Florian Westphal 
netfilter: ip6_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: ip_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: arp_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: x_tables: don't reject valid target size on some architectures

Florian Westphal 
netfilter: x_tables: validate all offsets and sizes in a rule

Florian Westphal 
netfilter: x_tables: check for bogus target offset

Florian Westphal 
netfilter: x_tables: check standard target size too

Florian Westphal 
netfilter: x_tables: add compat version of xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: assert minimum target size

Florian Westphal 
netfilter: x_tables: kill check_entry helper

Florian Westphal 
netfilter: x_tables: add and use xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: validate targets of jumps

Florian Westphal 
netfilter: x_tables: don't move to non-existent next rule

Willy Tarreau 
pipe: limit the per-user amount of pages allocated in pipes

Greg Kroah-Hartman 
xfs: fix up backport error in fs/xfs/xfs_inode.c

Florian Westphal 
netfilter: x_tables: fix unconditional helper

Florian Westphal 
netfilter: x_tables: make sure e->next_offset covers remaining blob size

Florian Westphal 
netfilter: x_tables: validate e->target_offset early

Russell Currey 
powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge

Ralf Baechle 
MIPS: Fix 64k page support for 32 bit kernels.

Al Viro 
fix d_walk()/non-delayed __d_free() race

Prasun Maiti 
wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

Jann Horn 
ecryptfs: forbid opening files without mmap handler

Helge Deller 
parisc: Fix pagefault crash in unaligned __get_user() call

Thomas Huth 
powerpc: Use privileged SPR number for MMCR2

Thomas Huth 
powerpc: Fix definition of SIAR and SDAR registers

Tom Lendacky 
crypto: ccp - Fix AES XTS error for request sizes above 4096

Russell King 
ARM: fix PTRACE_SETVFPREGS on SMP systems

Paolo Bonzini 
KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS

Yuchung Cheng 
tcp: record TLP and ER timer stats in v6 stats

Edward Cree 
sfc: on MC reset, clear PIO buffer linkage in TXQs

Herbert Xu 
netlink: Fix dump skb leak/double free


-

Diffstat:

 Documentation/sysctl/fs.txt  |  23 ++
 Makefile |   4 +-
 arch/arm/kernel/ptrace.c |   2 +-
 arch/mips/include/asm/processor.h|   2 +-
 arch/parisc/kernel/unaligned.c   |  10 +-
 arch/powerpc/include/asm/reg.h   |   6 +-
 arch/powerpc/platforms/pseries/eeh_pseries.c |  51 +++--
 arch/x86/kvm/x86.c   |   5 +
 drivers/crypto/ccp/ccp-crypto-aes-xts.c  |  17 +-
 drivers/net/ethernet/sfc/ef10.c  |  16 ++
 fs/dcache.c  |   4 +-
 fs/ecryptfs/kthread.c|  13 +-
 fs/pipe.c|  47 +++-
 fs/xfs/xfs_inode.c   |   2 +-
 include/linux/netfilter/x_tables.h   |   9 +-
 include/linux/pipe_fs_i.h

Re: [PATCH 3.14 00/29] 3.14.73-stable review -rc2

2016-06-22 Thread Greg Kroah-Hartman
-rc2!

Please test this...

This is the start of the stable review cycle for the 3.14.73 release.
There are 35 patches in this series, all will be posted as a response
to this one.  If anyone has any issues with these being applied, please
let me know.

Responses should be made by Sat Jun 25 04:50:44 UTC 2016.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.14.73-rc2.gz
or in the git tree and branch at:
  git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
linux-3.14.y
and the diffstat can be found below.

thanks,

greg k-h

-
Pseudo-Shortlog of commits:

Greg Kroah-Hartman 
Linux 3.14.73-rc2

Florian Westphal 
netfilter: x_tables: do compat validation via translate_table

Dave Jones 
netfilter: ensure number of counters is >0 in do_replace()

Florian Westphal 
netfilter: x_tables: xt_compat_match_from_user doesn't need a retval

Florian Westphal 
netfilter: ip6_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: ip_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: arp_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: x_tables: don't reject valid target size on some architectures

Florian Westphal 
netfilter: x_tables: validate all offsets and sizes in a rule

Florian Westphal 
netfilter: x_tables: check for bogus target offset

Florian Westphal 
netfilter: x_tables: check standard target size too

Florian Westphal 
netfilter: x_tables: add compat version of xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: assert minimum target size

Florian Westphal 
netfilter: x_tables: kill check_entry helper

Florian Westphal 
netfilter: x_tables: add and use xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: validate targets of jumps

Florian Westphal 
netfilter: x_tables: don't move to non-existent next rule

Willy Tarreau 
pipe: limit the per-user amount of pages allocated in pipes

Greg Kroah-Hartman 
xfs: fix up backport error in fs/xfs/xfs_inode.c

Florian Westphal 
netfilter: x_tables: fix unconditional helper

Florian Westphal 
netfilter: x_tables: make sure e->next_offset covers remaining blob size

Florian Westphal 
netfilter: x_tables: validate e->target_offset early

Russell Currey 
powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge

Ralf Baechle 
MIPS: Fix 64k page support for 32 bit kernels.

Al Viro 
fix d_walk()/non-delayed __d_free() race

Prasun Maiti 
wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

Jann Horn 
ecryptfs: forbid opening files without mmap handler

Helge Deller 
parisc: Fix pagefault crash in unaligned __get_user() call

Thomas Huth 
powerpc: Use privileged SPR number for MMCR2

Thomas Huth 
powerpc: Fix definition of SIAR and SDAR registers

Tom Lendacky 
crypto: ccp - Fix AES XTS error for request sizes above 4096

Russell King 
ARM: fix PTRACE_SETVFPREGS on SMP systems

Paolo Bonzini 
KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS

Yuchung Cheng 
tcp: record TLP and ER timer stats in v6 stats

Edward Cree 
sfc: on MC reset, clear PIO buffer linkage in TXQs

Herbert Xu 
netlink: Fix dump skb leak/double free


-

Diffstat:

 Documentation/sysctl/fs.txt  |  23 ++
 Makefile |   4 +-
 arch/arm/kernel/ptrace.c |   2 +-
 arch/mips/include/asm/processor.h|   2 +-
 arch/parisc/kernel/unaligned.c   |  10 +-
 arch/powerpc/include/asm/reg.h   |   6 +-
 arch/powerpc/platforms/pseries/eeh_pseries.c |  51 +++--
 arch/x86/kvm/x86.c   |   5 +
 drivers/crypto/ccp/ccp-crypto-aes-xts.c  |  17 +-
 drivers/net/ethernet/sfc/ef10.c  |  16 ++
 fs/dcache.c  |   4 +-
 fs/ecryptfs/kthread.c|  13 +-
 fs/pipe.c|  47 +++-
 fs/xfs/xfs_inode.c   |   2 +-
 include/linux/netfilter/x_tables.h   |   9 +-
 include/linux/pipe_fs_i.h|   4 +
 include/linux/sched.h|   1 +
 kernel/sysctl.c  |  14 ++
 net/bridge/netfilter/ebtables.c  |   4 +
 net/ipv4/netfilter/arp_tables.c  | 279 +---
 net/ipv4/netfilter/ip_tables.c   | 312 +--
 net/ipv6/netfilter/ip6_tables.c  | 305 +-
 net/ipv6/tcp_ipv6.c  |   4 +-
 net/netfilter/x_tables.c | 171 ++-
 net/netlink/af_netlink.c |   7 +-
 net/wireless/wext-core.c |  25 ++-
 26 files changed, 708 

Re: [PATCH 4.4 00/75] 4.4.14-stable review -rc2

2016-06-22 Thread Greg Kroah-Hartman
-rc2!

This is the start of the stable review cycle for the 4.4.14 release.
There are 81 patches in this series, all will be posted as a response
to this one.  If anyone has any issues with these being applied, please
let me know.

Responses should be made by Sat Jun 25 04:51:37 UTC 2016.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.14-rc2.gz
or in the git tree and branch at:
  git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
linux-4.4.y
and the diffstat can be found below.

thanks,

greg k-h

-
Pseudo-Shortlog of commits:

Greg Kroah-Hartman 
Linux 4.4.14-rc2

Florian Westphal 
netfilter: x_tables: introduce and use xt_copy_counters_from_user

Florian Westphal 
netfilter: x_tables: do compat validation via translate_table

Florian Westphal 
netfilter: x_tables: xt_compat_match_from_user doesn't need a retval

Florian Westphal 
netfilter: ip6_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: ip_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: arp_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: x_tables: don't reject valid target size on some architectures

Florian Westphal 
netfilter: x_tables: validate all offsets and sizes in a rule

Florian Westphal 
netfilter: x_tables: check for bogus target offset

Florian Westphal 
netfilter: x_tables: check standard target size too

Florian Westphal 
netfilter: x_tables: add compat version of xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: assert minimum target size

Florian Westphal 
netfilter: x_tables: kill check_entry helper

Florian Westphal 
netfilter: x_tables: add and use xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: validate targets of jumps

Florian Westphal 
netfilter: x_tables: don't move to non-existent next rule

Maarten Lankhorst 
drm/core: Do not preserve framebuffer on rmfb, v4.

Tadeusz Struk 
crypto: qat - fix adf_ctl_drv.c:undefined reference to adf_init_pf_wq

Florian Westphal 
netfilter: x_tables: fix unconditional helper

Florian Westphal 
netfilter: x_tables: make sure e->next_offset covers remaining blob size

Florian Westphal 
netfilter: x_tables: validate e->target_offset early

Ralf Baechle 
MIPS: Fix 64k page support for 32 bit kernels.

David S. Miller 
sparc64: Fix return from trap window fill crashes.

David S. Miller 
sparc: Harden signal return frame checks.

David S. Miller 
sparc64: Take ctx_alloc_lock properly in hugetlb_setup().

Nitin Gupta 
sparc64: Reduce TLB flushes during hugepte changes

Babu Moger 
sparc/PCI: Fix for panic while enabling SR-IOV

David S. Miller 
sparc64: Fix sparc64_set_context stack handling.

Nitin Gupta 
sparc64: Fix numa node distance initialization

David S. Miller 
sparc64: Fix bootup regressions on some Kconfig combinations.

Mike Frysinger 
sparc: Fix system call tracing register handling.

Al Viro 
fix d_walk()/non-delayed __d_free() race

Jann Horn 
sched: panic on corrupted stack end

Jann Horn 
proc: prevent stacking filesystems on top

Andy Lutomirski 
x86/entry/traps: Don't force in_interrupt() to return true in IST handlers

Prasun Maiti 
wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

Jann Horn 
ecryptfs: forbid opening files without mmap handler

Tejun Heo 
memcg: add RCU locking around css_for_each_descendant_pre() in 
memcg_offline_kmem()

Helge Deller 
parisc: Fix pagefault crash in unaligned __get_user() call

hongkun.cao 
pinctrl: mediatek: fix dual-edge code defect

Thomas Huth 
powerpc/pseries: Add POWER8NVL support to ibm,client-architecture-support 
call

Thomas Huth 
powerpc: Use privileged SPR number for MMCR2

Thomas Huth 
powerpc: Fix definition of SIAR and SDAR registers

Russell Currey 
powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge

Will 

Re: [PATCH 4.4 00/75] 4.4.14-stable review -rc2

2016-06-22 Thread Greg Kroah-Hartman
-rc2!

This is the start of the stable review cycle for the 4.4.14 release.
There are 81 patches in this series, all will be posted as a response
to this one.  If anyone has any issues with these being applied, please
let me know.

Responses should be made by Sat Jun 25 04:51:37 UTC 2016.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.14-rc2.gz
or in the git tree and branch at:
  git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
linux-4.4.y
and the diffstat can be found below.

thanks,

greg k-h

-
Pseudo-Shortlog of commits:

Greg Kroah-Hartman 
Linux 4.4.14-rc2

Florian Westphal 
netfilter: x_tables: introduce and use xt_copy_counters_from_user

Florian Westphal 
netfilter: x_tables: do compat validation via translate_table

Florian Westphal 
netfilter: x_tables: xt_compat_match_from_user doesn't need a retval

Florian Westphal 
netfilter: ip6_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: ip_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: arp_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: x_tables: don't reject valid target size on some architectures

Florian Westphal 
netfilter: x_tables: validate all offsets and sizes in a rule

Florian Westphal 
netfilter: x_tables: check for bogus target offset

Florian Westphal 
netfilter: x_tables: check standard target size too

Florian Westphal 
netfilter: x_tables: add compat version of xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: assert minimum target size

Florian Westphal 
netfilter: x_tables: kill check_entry helper

Florian Westphal 
netfilter: x_tables: add and use xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: validate targets of jumps

Florian Westphal 
netfilter: x_tables: don't move to non-existent next rule

Maarten Lankhorst 
drm/core: Do not preserve framebuffer on rmfb, v4.

Tadeusz Struk 
crypto: qat - fix adf_ctl_drv.c:undefined reference to adf_init_pf_wq

Florian Westphal 
netfilter: x_tables: fix unconditional helper

Florian Westphal 
netfilter: x_tables: make sure e->next_offset covers remaining blob size

Florian Westphal 
netfilter: x_tables: validate e->target_offset early

Ralf Baechle 
MIPS: Fix 64k page support for 32 bit kernels.

David S. Miller 
sparc64: Fix return from trap window fill crashes.

David S. Miller 
sparc: Harden signal return frame checks.

David S. Miller 
sparc64: Take ctx_alloc_lock properly in hugetlb_setup().

Nitin Gupta 
sparc64: Reduce TLB flushes during hugepte changes

Babu Moger 
sparc/PCI: Fix for panic while enabling SR-IOV

David S. Miller 
sparc64: Fix sparc64_set_context stack handling.

Nitin Gupta 
sparc64: Fix numa node distance initialization

David S. Miller 
sparc64: Fix bootup regressions on some Kconfig combinations.

Mike Frysinger 
sparc: Fix system call tracing register handling.

Al Viro 
fix d_walk()/non-delayed __d_free() race

Jann Horn 
sched: panic on corrupted stack end

Jann Horn 
proc: prevent stacking filesystems on top

Andy Lutomirski 
x86/entry/traps: Don't force in_interrupt() to return true in IST handlers

Prasun Maiti 
wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

Jann Horn 
ecryptfs: forbid opening files without mmap handler

Tejun Heo 
memcg: add RCU locking around css_for_each_descendant_pre() in 
memcg_offline_kmem()

Helge Deller 
parisc: Fix pagefault crash in unaligned __get_user() call

hongkun.cao 
pinctrl: mediatek: fix dual-edge code defect

Thomas Huth 
powerpc/pseries: Add POWER8NVL support to ibm,client-architecture-support 
call

Thomas Huth 
powerpc: Use privileged SPR number for MMCR2

Thomas Huth 
powerpc: Fix definition of SIAR and SDAR registers

Russell Currey 
powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge

Will Deacon 
arm64: mm: always take dirty state from new pte in ptep_set_access_flags

Catalin Marinas 
arm64: Provide "model name" in /proc/cpuinfo for PER_LINUX32 tasks

Tom Lendacky 
crypto: ccp - Fix AES XTS error for request sizes above 4096

Arnd Bergmann 
crypto: public_key: select CRYPTO_AKCIPHER

Marc Zyngier 
irqchip/gic-v3: Fix ICC_SGI1R_EL1.INTID decoding mask

Michael Holzheu 
s390/bpf: reduce maximum program size to 64 KB

Michael Holzheu 
s390/bpf: fix recache skb->data/hlen for skb_vlan_push/pop

Ben Dooks 
gpio: bcm-kona: fix bcm_kona_gpio_reset() warnings

Russell King 
ARM: fix PTRACE_SETVFPREGS on SMP systems

Torsten Hilbrich 
ALSA: hda/realtek: Add T560 docking unit fixup

Kailang Yang 
ALSA: hda/realtek - Add support for new codecs ALC700/ALC701/ALC703

Kailang Yang 
ALSA: hda/realtek - 

[PATCH 4.6 00/87] 4.6.3-stable review -rc2

2016-06-22 Thread Greg Kroah-Hartman
Let's try a -rc2!

This is the start of the stable review cycle for the 4.6.3 release.
There are 87 patches in this series, all will be posted as a response
to this one.  If anyone has any issues with these being applied, please
let me know.

Responses should be made by Sat Jun 25 04:47:50 UTC 2016.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.6.3-rc2.gz
or in the git tree and branch at:
  git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
linux-4.6.y
and the diffstat can be found below.

thanks,

greg k-h

-
Pseudo-Shortlog of commits:

Greg Kroah-Hartman 
Linux 4.6.3-rc2

Florian Westphal 
netfilter: x_tables: introduce and use xt_copy_counters_from_user

Florian Westphal 
netfilter: x_tables: do compat validation via translate_table

Florian Westphal 
netfilter: x_tables: xt_compat_match_from_user doesn't need a retval

Florian Westphal 
netfilter: ip6_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: ip_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: arp_tables: simplify translate_compat_table args

Greg Kroah-Hartman 
Revert "drm/i915: Exit cherryview_irq_handler() after one pass"

Florian Westphal 
netfilter: x_tables: don't reject valid target size on some architectures

Florian Westphal 
netfilter: x_tables: validate all offsets and sizes in a rule

Florian Westphal 
netfilter: x_tables: check for bogus target offset

Florian Westphal 
netfilter: x_tables: check standard target size too

Florian Westphal 
netfilter: x_tables: add compat version of xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: assert minimum target size

Florian Westphal 
netfilter: x_tables: kill check_entry helper

Florian Westphal 
netfilter: x_tables: add and use xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: validate targets of jumps

Florian Westphal 
netfilter: x_tables: don't move to non-existent next rule

Maarten Lankhorst 
drm/core: Do not preserve framebuffer on rmfb, v4.

Helmut Grohne 
gpio: zynq: initialize clock even without CONFIG_PM

Shubhrajyoti Datta 
gpio: zynq: Fix the error path

David S. Miller 
sparc64: Fix return from trap window fill crashes.

David S. Miller 
sparc: Harden signal return frame checks.

David S. Miller 
sparc64: Take ctx_alloc_lock properly in hugetlb_setup().

Nitin Gupta 
sparc64: Reduce TLB flushes during hugepte changes

Al Viro 
fix d_walk()/non-delayed __d_free() race

Jann Horn 
sched: panic on corrupted stack end

Jann Horn 
proc: prevent stacking filesystems on top

Andy Lutomirski 
x86/entry/traps: Don't force in_interrupt() to return true in IST handlers

Gerald Schaefer 
mm: thp: broken page count after commit aa88b68c3b1d

Prasun Maiti 
wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

Jann Horn 
ecryptfs: forbid opening files without mmap handler

Tejun Heo 
memcg: add RCU locking around css_for_each_descendant_pre() in 
memcg_offline_kmem()

Helge Deller 
parisc: Fix pagefault crash in unaligned __get_user() call

hongkun.cao 
pinctrl: mediatek: fix dual-edge code defect

Aneesh Kumar K.V 
powerpc/mm/hash: Fix the reference bit update when handling hash fault

Thomas Huth 
powerpc/pseries: Add POWER8NVL support to ibm,client-architecture-support 
call

Thomas Huth 
powerpc: Use privileged SPR number for MMCR2

Thomas Huth 
powerpc: Fix definition of SIAR and SDAR registers

Russell Currey 
powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge

Will Deacon 
arm64: mm: always take dirty state from new pte in ptep_set_access_flags

Catalin Marinas 
arm64: Provide "model name" in /proc/cpuinfo for PER_LINUX32 tasks

Tom Lendacky 
crypto: ccp - Fix AES XTS error for request sizes above 4096

Arnd Bergmann 
crypto: public_key: select CRYPTO_AKCIPHER

Marc Zyngier 

[PATCH 4.6 00/87] 4.6.3-stable review -rc2

2016-06-22 Thread Greg Kroah-Hartman
Let's try a -rc2!

This is the start of the stable review cycle for the 4.6.3 release.
There are 87 patches in this series, all will be posted as a response
to this one.  If anyone has any issues with these being applied, please
let me know.

Responses should be made by Sat Jun 25 04:47:50 UTC 2016.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.6.3-rc2.gz
or in the git tree and branch at:
  git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
linux-4.6.y
and the diffstat can be found below.

thanks,

greg k-h

-
Pseudo-Shortlog of commits:

Greg Kroah-Hartman 
Linux 4.6.3-rc2

Florian Westphal 
netfilter: x_tables: introduce and use xt_copy_counters_from_user

Florian Westphal 
netfilter: x_tables: do compat validation via translate_table

Florian Westphal 
netfilter: x_tables: xt_compat_match_from_user doesn't need a retval

Florian Westphal 
netfilter: ip6_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: ip_tables: simplify translate_compat_table args

Florian Westphal 
netfilter: arp_tables: simplify translate_compat_table args

Greg Kroah-Hartman 
Revert "drm/i915: Exit cherryview_irq_handler() after one pass"

Florian Westphal 
netfilter: x_tables: don't reject valid target size on some architectures

Florian Westphal 
netfilter: x_tables: validate all offsets and sizes in a rule

Florian Westphal 
netfilter: x_tables: check for bogus target offset

Florian Westphal 
netfilter: x_tables: check standard target size too

Florian Westphal 
netfilter: x_tables: add compat version of xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: assert minimum target size

Florian Westphal 
netfilter: x_tables: kill check_entry helper

Florian Westphal 
netfilter: x_tables: add and use xt_check_entry_offsets

Florian Westphal 
netfilter: x_tables: validate targets of jumps

Florian Westphal 
netfilter: x_tables: don't move to non-existent next rule

Maarten Lankhorst 
drm/core: Do not preserve framebuffer on rmfb, v4.

Helmut Grohne 
gpio: zynq: initialize clock even without CONFIG_PM

Shubhrajyoti Datta 
gpio: zynq: Fix the error path

David S. Miller 
sparc64: Fix return from trap window fill crashes.

David S. Miller 
sparc: Harden signal return frame checks.

David S. Miller 
sparc64: Take ctx_alloc_lock properly in hugetlb_setup().

Nitin Gupta 
sparc64: Reduce TLB flushes during hugepte changes

Al Viro 
fix d_walk()/non-delayed __d_free() race

Jann Horn 
sched: panic on corrupted stack end

Jann Horn 
proc: prevent stacking filesystems on top

Andy Lutomirski 
x86/entry/traps: Don't force in_interrupt() to return true in IST handlers

Gerald Schaefer 
mm: thp: broken page count after commit aa88b68c3b1d

Prasun Maiti 
wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

Jann Horn 
ecryptfs: forbid opening files without mmap handler

Tejun Heo 
memcg: add RCU locking around css_for_each_descendant_pre() in 
memcg_offline_kmem()

Helge Deller 
parisc: Fix pagefault crash in unaligned __get_user() call

hongkun.cao 
pinctrl: mediatek: fix dual-edge code defect

Aneesh Kumar K.V 
powerpc/mm/hash: Fix the reference bit update when handling hash fault

Thomas Huth 
powerpc/pseries: Add POWER8NVL support to ibm,client-architecture-support 
call

Thomas Huth 
powerpc: Use privileged SPR number for MMCR2

Thomas Huth 
powerpc: Fix definition of SIAR and SDAR registers

Russell Currey 
powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge

Will Deacon 
arm64: mm: always take dirty state from new pte in ptep_set_access_flags

Catalin Marinas 
arm64: Provide "model name" in /proc/cpuinfo for PER_LINUX32 tasks

Tom Lendacky 
crypto: ccp - Fix AES XTS error for request sizes above 4096

Arnd Bergmann 
crypto: public_key: select CRYPTO_AKCIPHER

Marc Zyngier 
irqchip/gic-v3: Fix ICC_SGI1R_EL1.INTID decoding mask

Michael Holzheu 
s390/bpf: reduce maximum program size to 64 KB

Michael Holzheu 
s390/bpf: fix recache skb->data/hlen for skb_vlan_push/pop

Ricardo Ribalda Delgado 
gpiolib: Fix unaligned used of reference counters

Ricardo Ribalda Delgado 
gpiolib: Fix NULL pointer deference

Ben Dooks 
gpio: bcm-kona: fix bcm_kona_gpio_reset() warnings

Linus Walleij 
gpio: bail out silently on NULL descriptors

Russell King 
ARM: fix PTRACE_SETVFPREGS on SMP systems

Torsten Hilbrich 
ALSA: hda/realtek: Add T560 docking unit fixup

Kailang Yang 
ALSA: hda/realtek - Add support for new codecs ALC700/ALC701/ALC703

Kailang Yang 
ALSA: hda/realtek - ALC256 speaker noise issue

AceLan Kao 
ALSA: hda - Fix headset mic detection problem for Dell machine

Vinod Koul 
ALSA: hda - Add PCI ID for 

[PATCH] dlm: Use kmemdup instead of kmalloc and memcpy

2016-06-22 Thread Amitoj Kaur Chawla
Replace calls to kmalloc followed by a memcpy with a direct call to
kmemdup.

The Coccinelle semantic patch used to make this change is as follows:
@@
expression from,to,size,flag;
statement S;
@@

-  to = \(kmalloc\|kzalloc\)(size,flag);
+  to = kmemdup(from,size,flag);
   if (to==NULL || ...) S
-  memcpy(to, from, size);

Signed-off-by: Amitoj Kaur Chawla 
---
 fs/dlm/lowcomms.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 1ab012a..963016c 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -1279,10 +1279,9 @@ static void init_local(void)
if (dlm_our_addr(, i))
break;
 
-   addr = kmalloc(sizeof(*addr), GFP_NOFS);
+   addr = kmemdup(, sizeof(*addr), GFP_NOFS);
if (!addr)
break;
-   memcpy(addr, , sizeof(*addr));
dlm_local_addr[dlm_local_count++] = addr;
}
 }
-- 
1.9.1



[PATCH] dlm: Use kmemdup instead of kmalloc and memcpy

2016-06-22 Thread Amitoj Kaur Chawla
Replace calls to kmalloc followed by a memcpy with a direct call to
kmemdup.

The Coccinelle semantic patch used to make this change is as follows:
@@
expression from,to,size,flag;
statement S;
@@

-  to = \(kmalloc\|kzalloc\)(size,flag);
+  to = kmemdup(from,size,flag);
   if (to==NULL || ...) S
-  memcpy(to, from, size);

Signed-off-by: Amitoj Kaur Chawla 
---
 fs/dlm/lowcomms.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 1ab012a..963016c 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -1279,10 +1279,9 @@ static void init_local(void)
if (dlm_our_addr(, i))
break;
 
-   addr = kmalloc(sizeof(*addr), GFP_NOFS);
+   addr = kmemdup(, sizeof(*addr), GFP_NOFS);
if (!addr)
break;
-   memcpy(addr, , sizeof(*addr));
dlm_local_addr[dlm_local_count++] = addr;
}
 }
-- 
1.9.1



Re: [PATCHv4 1/1] thermal: core: call thermal_zone_device_update() after mode update

2016-06-22 Thread Darren Hart
On Wed, Jun 22, 2016 at 08:03:18AM -0700, Eduardo Valentin wrote:
> Because several drivers do the following pattern:
> .set_mode()
>...
>local_data->mode = new_mode;
>thermal_zone_device_update(tz);
> 
> makes sense to simply do the thermal_zone_device_update()
> in thermal core, after setting the new mode.
> 
> Also, this patch also remove deadlocks on drivers that
> call thermal_zone_device_update() on .set_mode(),
> as .set_mode()  is now called always with tz->lock held.
> 
> Cc: "Rafael J. Wysocki" 
> Cc: Len Brown 
> Cc: linux-a...@vger.kernel.org
> Cc: "Lee, Chun-Yi" 
> Cc: Darren Hart 
> Cc: Zhang Rui 
> Cc: Keerthy 
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-o...@vger.kernel.org
> Cc: platform-driver-...@vger.kernel.org
> Cc: linux...@vger.kernel.org
> Signed-off-by: Eduardo Valentin 

+Peter Feuerer 

Peter, any concerns regarding the acerhdf driver?

> ---
> Hello,
> 
> V3->V4:
> - ti-soc: Removed extra locking from TI SoC in set_mode
> - ACPI: Kept the update on check as it is called on other places
> 
> BR,
> 
> Eduardo
> 
>  drivers/acpi/thermal.c | 1 -
>  drivers/platform/x86/acerhdf.c | 1 -
>  drivers/thermal/imx_thermal.c  | 1 -
>  drivers/thermal/of-thermal.c   | 5 -
>  drivers/thermal/thermal_sysfs.c| 1 +
>  drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 5 -
>  6 files changed, 1 insertion(+), 13 deletions(-)
> 
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 82707f9..03c3460 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -581,7 +581,6 @@ static int thermal_set_mode(struct thermal_zone_device 
> *thermal,
>   ACPI_DEBUG_PRINT((ACPI_DB_INFO,
>   "%s kernel ACPI thermal control\n",
>   tz->tz_enabled ? "Enable" : "Disable"));
> - acpi_thermal_check(tz);
>   }
>   return 0;
>  }
> diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
> index 460fa67..aee33ba 100644
> --- a/drivers/platform/x86/acerhdf.c
> +++ b/drivers/platform/x86/acerhdf.c
> @@ -405,7 +405,6 @@ static inline void acerhdf_enable_kernelmode(void)
>   kernelmode = 1;
>  
>   thz_dev->polling_delay = interval*1000;
> - thermal_zone_device_update(thz_dev);
>   pr_notice("kernel mode fan control ON\n");
>  }
>  
> diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
> index c5547bd..a413eb6 100644
> --- a/drivers/thermal/imx_thermal.c
> +++ b/drivers/thermal/imx_thermal.c
> @@ -246,7 +246,6 @@ static int imx_set_mode(struct thermal_zone_device *tz,
>   }
>  
>   data->mode = mode;
> - thermal_zone_device_update(tz);
>  
>   return 0;
>  }
> diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
> index b8e509c..95c47da 100644
> --- a/drivers/thermal/of-thermal.c
> +++ b/drivers/thermal/of-thermal.c
> @@ -282,17 +282,12 @@ static int of_thermal_set_mode(struct 
> thermal_zone_device *tz,
>  {
>   struct __thermal_zone *data = tz->devdata;
>  
> - mutex_lock(>lock);
> -
>   if (mode == THERMAL_DEVICE_ENABLED)
>   tz->polling_delay = data->polling_delay;
>   else
>   tz->polling_delay = 0;
>  
> - mutex_unlock(>lock);
> -
>   data->mode = mode;
> - thermal_zone_device_update(tz);
>  
>   return 0;
>  }
> diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
> index 743df50..3d0dc30 100644
> --- a/drivers/thermal/thermal_sysfs.c
> +++ b/drivers/thermal/thermal_sysfs.c
> @@ -100,6 +100,7 @@ mode_store(struct device *dev, struct device_attribute 
> *attr,
>   mutex_lock(>lock);
>   result = tz->ops->set_mode(tz, mode);
>   mutex_unlock(>lock);
> + thermal_zone_device_update(tz);
>  
>   if (result)
>   return result;
> diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c 
> b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
> index 15c0a9a..5dce053 100644
> --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
> +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
> @@ -193,19 +193,14 @@ static int ti_thermal_set_mode(struct 
> thermal_zone_device *thermal,
>   return 0;
>   }
>  
> - mutex_lock(>ti_thermal->lock);
> -
>   if (mode == THERMAL_DEVICE_ENABLED)
>   data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
>   else
>   data->ti_thermal->polling_delay = 0;
>  
> - mutex_unlock(>ti_thermal->lock);
> -
>   data->mode = mode;
>   ti_bandgap_write_update_interval(bgp, data->sensor_id,
>   data->ti_thermal->polling_delay);
> - thermal_zone_device_update(data->ti_thermal);
>   

Re: [PATCHv4 1/1] thermal: core: call thermal_zone_device_update() after mode update

2016-06-22 Thread Darren Hart
On Wed, Jun 22, 2016 at 08:03:18AM -0700, Eduardo Valentin wrote:
> Because several drivers do the following pattern:
> .set_mode()
>...
>local_data->mode = new_mode;
>thermal_zone_device_update(tz);
> 
> makes sense to simply do the thermal_zone_device_update()
> in thermal core, after setting the new mode.
> 
> Also, this patch also remove deadlocks on drivers that
> call thermal_zone_device_update() on .set_mode(),
> as .set_mode()  is now called always with tz->lock held.
> 
> Cc: "Rafael J. Wysocki" 
> Cc: Len Brown 
> Cc: linux-a...@vger.kernel.org
> Cc: "Lee, Chun-Yi" 
> Cc: Darren Hart 
> Cc: Zhang Rui 
> Cc: Keerthy 
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-o...@vger.kernel.org
> Cc: platform-driver-...@vger.kernel.org
> Cc: linux...@vger.kernel.org
> Signed-off-by: Eduardo Valentin 

+Peter Feuerer 

Peter, any concerns regarding the acerhdf driver?

> ---
> Hello,
> 
> V3->V4:
> - ti-soc: Removed extra locking from TI SoC in set_mode
> - ACPI: Kept the update on check as it is called on other places
> 
> BR,
> 
> Eduardo
> 
>  drivers/acpi/thermal.c | 1 -
>  drivers/platform/x86/acerhdf.c | 1 -
>  drivers/thermal/imx_thermal.c  | 1 -
>  drivers/thermal/of-thermal.c   | 5 -
>  drivers/thermal/thermal_sysfs.c| 1 +
>  drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 5 -
>  6 files changed, 1 insertion(+), 13 deletions(-)
> 
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 82707f9..03c3460 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -581,7 +581,6 @@ static int thermal_set_mode(struct thermal_zone_device 
> *thermal,
>   ACPI_DEBUG_PRINT((ACPI_DB_INFO,
>   "%s kernel ACPI thermal control\n",
>   tz->tz_enabled ? "Enable" : "Disable"));
> - acpi_thermal_check(tz);
>   }
>   return 0;
>  }
> diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
> index 460fa67..aee33ba 100644
> --- a/drivers/platform/x86/acerhdf.c
> +++ b/drivers/platform/x86/acerhdf.c
> @@ -405,7 +405,6 @@ static inline void acerhdf_enable_kernelmode(void)
>   kernelmode = 1;
>  
>   thz_dev->polling_delay = interval*1000;
> - thermal_zone_device_update(thz_dev);
>   pr_notice("kernel mode fan control ON\n");
>  }
>  
> diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
> index c5547bd..a413eb6 100644
> --- a/drivers/thermal/imx_thermal.c
> +++ b/drivers/thermal/imx_thermal.c
> @@ -246,7 +246,6 @@ static int imx_set_mode(struct thermal_zone_device *tz,
>   }
>  
>   data->mode = mode;
> - thermal_zone_device_update(tz);
>  
>   return 0;
>  }
> diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
> index b8e509c..95c47da 100644
> --- a/drivers/thermal/of-thermal.c
> +++ b/drivers/thermal/of-thermal.c
> @@ -282,17 +282,12 @@ static int of_thermal_set_mode(struct 
> thermal_zone_device *tz,
>  {
>   struct __thermal_zone *data = tz->devdata;
>  
> - mutex_lock(>lock);
> -
>   if (mode == THERMAL_DEVICE_ENABLED)
>   tz->polling_delay = data->polling_delay;
>   else
>   tz->polling_delay = 0;
>  
> - mutex_unlock(>lock);
> -
>   data->mode = mode;
> - thermal_zone_device_update(tz);
>  
>   return 0;
>  }
> diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
> index 743df50..3d0dc30 100644
> --- a/drivers/thermal/thermal_sysfs.c
> +++ b/drivers/thermal/thermal_sysfs.c
> @@ -100,6 +100,7 @@ mode_store(struct device *dev, struct device_attribute 
> *attr,
>   mutex_lock(>lock);
>   result = tz->ops->set_mode(tz, mode);
>   mutex_unlock(>lock);
> + thermal_zone_device_update(tz);
>  
>   if (result)
>   return result;
> diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c 
> b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
> index 15c0a9a..5dce053 100644
> --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
> +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
> @@ -193,19 +193,14 @@ static int ti_thermal_set_mode(struct 
> thermal_zone_device *thermal,
>   return 0;
>   }
>  
> - mutex_lock(>ti_thermal->lock);
> -
>   if (mode == THERMAL_DEVICE_ENABLED)
>   data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
>   else
>   data->ti_thermal->polling_delay = 0;
>  
> - mutex_unlock(>ti_thermal->lock);
> -
>   data->mode = mode;
>   ti_bandgap_write_update_interval(bgp, data->sensor_id,
>   data->ti_thermal->polling_delay);
> - thermal_zone_device_update(data->ti_thermal);
>   dev_dbg(>device, "thermal polling set for duration=%d msec\n",
>   data->ti_thermal->polling_delay);
>  
> -- 
> 2.1.4
> 
> 

-- 
Darren Hart
Intel Open 

[PATCH] tipc: Use kmemdup instead of kmalloc and memcpy

2016-06-22 Thread Amitoj Kaur Chawla
Replace calls to kmalloc followed by a memcpy with a direct call to
kmemdup.

The Coccinelle semantic patch used to make this change is as follows:
@@
expression from,to,size,flag;
statement S;
@@

-  to = \(kmalloc\|kzalloc\)(size,flag);
+  to = kmemdup(from,size,flag);
   if (to==NULL || ...) S
-  memcpy(to, from, size);

Signed-off-by: Amitoj Kaur Chawla 
---
 net/tipc/server.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/tipc/server.c b/net/tipc/server.c
index 2446bfb..38a6f33 100644
--- a/net/tipc/server.c
+++ b/net/tipc/server.c
@@ -411,13 +411,12 @@ static struct outqueue_entry *tipc_alloc_entry(void 
*data, int len)
if (!entry)
return NULL;
 
-   buf = kmalloc(len, GFP_ATOMIC);
+   buf = kmemdup(data, len, GFP_ATOMIC);
if (!buf) {
kfree(entry);
return NULL;
}
 
-   memcpy(buf, data, len);
entry->iov.iov_base = buf;
entry->iov.iov_len = len;
 
-- 
1.9.1



[PATCH] tipc: Use kmemdup instead of kmalloc and memcpy

2016-06-22 Thread Amitoj Kaur Chawla
Replace calls to kmalloc followed by a memcpy with a direct call to
kmemdup.

The Coccinelle semantic patch used to make this change is as follows:
@@
expression from,to,size,flag;
statement S;
@@

-  to = \(kmalloc\|kzalloc\)(size,flag);
+  to = kmemdup(from,size,flag);
   if (to==NULL || ...) S
-  memcpy(to, from, size);

Signed-off-by: Amitoj Kaur Chawla 
---
 net/tipc/server.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/tipc/server.c b/net/tipc/server.c
index 2446bfb..38a6f33 100644
--- a/net/tipc/server.c
+++ b/net/tipc/server.c
@@ -411,13 +411,12 @@ static struct outqueue_entry *tipc_alloc_entry(void 
*data, int len)
if (!entry)
return NULL;
 
-   buf = kmalloc(len, GFP_ATOMIC);
+   buf = kmemdup(data, len, GFP_ATOMIC);
if (!buf) {
kfree(entry);
return NULL;
}
 
-   memcpy(buf, data, len);
entry->iov.iov_base = buf;
entry->iov.iov_len = len;
 
-- 
1.9.1



Re: futex: Allow FUTEX_CLOCK_REALTIME with FUTEX_WAIT op

2016-06-22 Thread Darren Hart
On Mon, Jun 20, 2016 at 04:26:52PM +0200, Matthieu CASTET wrote:
> Hi,
> 
> the commit 337f13046ff03717a9e99675284a817527440a49 is saying that it
> change to syscall to an equivalent to FUTEX_WAIT_BITSET |
> FUTEX_CLOCK_REALTIME with a bitset of FUTEX_BITSET_MATCH_ANY.
> 
> It seems wrong to me, because in case of FUTEX_WAIT, in
> "SYSCALL_DEFINE6(futex", we convert relative timeout to absolute
> timeout [1].
> 
> So FUTEX_CLOCK_REALTIME | FUTEX_WAIT is expecting a relative timeout
> when FUTEX_WAIT_BITSET take an absolute timeout.
> 
> To make it work you have to use something like the (untested) attached
> patch.

+Eric Dumazet

Thanks for reporting Matthieu,

FUTEX_WAIT traditionally used a relative timeout with CLOCK_MONOTONIC while
FUTEX_WAIT_BITSET could use either ??? based on the FUTEX_CLOCK_ flag used. The
man page is not particularly clear on this:

http://man7.org/linux/man-pages/man2/futex.2.html

"
The FUTEX_WAIT_BITSET operation also interprets the timeout argument
differently from FUTEX_WAIT.  See the discussion of FUTEX_CLOCK_REALTIME,
above.
"

Matthew Kerrisk:
I think this language could be removed now that we support the
FUTEX_CLOCK_REALTIME flag for both futex ops.

As for the intended behavior of the FUTEX_CLOCK_REALTIME flag:


FUTEX_CLOCK_REALTIME (since Linux 2.6.28)
This option bit can be employed only with the FUTEX_WAIT_BITSET,
FUTEX_WAIT_REQUEUE_PI, and FUTEX_WAIT (since Linux 4.5) operations.

(NOTE: FUTEX_WAIT was recently added after the patch in question here)

If this option is set, the kernel treats timeout as an absolute time based
on CLOCK_REALTIME.

If this option is not set, the kernel treats timeout as a relative time,
measured against the CLOCK_MONOTONIC clock.


This supports your argument Matthieu. The assumption of a relative timeout for
FUTEX_WAIT in SYSCALL_DEFINE6 needs to be updated to account for FUTEX_WAIT now
honoring the FUTEX_CLOCK_REALTIME flag, which treats the timeout as absolute.

However, I don't think the patch below is correct. The existing logic
determines the type of timeout based on the futex_op when it should instead
determine the type of timeout based on the FUTEX_CLOCK_REALTIME flag.

My reading of the man page is that FUTEX_WAIT_BITSET abides by the timeout
interpretation defined by the FUTEX_CLOCK_REALTIME attribute, so
SYSCALL_DEFINE6 was misbehaving for FUTEX_WAIT|FUTEX_CLOCK_REALTIME (where the
timeout should have been treated as absolute) as well as for
FUTEX_WAIT_BITSET|FUTEX_CLOCK_MONOTONIC (where the timeout should have been
treated as relative).

Consider the following:

diff --git a/kernel/futex.c b/kernel/futex.c
index 33664f7..fa2af29 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -3230,7 +3230,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, 
val,
return -EINVAL;
 
t = timespec_to_ktime(ts);
-   if (cmd == FUTEX_WAIT)
+   if (!(cmd & FUTEX_CLOCK_REALTIME))
t = ktime_add_safe(ktime_get(), t);
tp = 
}

The concern for me is whether the code is incorrect, or if the man page is
incorrect. Does existing userspace code expect the FUTEX_WAIT_BITSET op to
always use an absolute timeout, regardless of the CLOCK used?





> 
> Matthieu
> 
> [1]
> if (cmd == FUTEX_WAIT)
> t = ktime_add_safe(ktime_get(), t);

> diff --git a/kernel/futex.c b/kernel/futex.c
> index 33664f7..4bee915 100644
> --- a/kernel/futex.c
> +++ b/kernel/futex.c
> @@ -3230,7 +3230,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, 
> u32, val,
>   return -EINVAL;
>  
>   t = timespec_to_ktime(ts);
> - if (cmd == FUTEX_WAIT)
> + if (cmd == FUTEX_WAIT && !(op & FUTEX_CLOCK_REALTIME))
>   t = ktime_add_safe(ktime_get(), t);
>   tp = 
>   }


-- 
Darren Hart
Intel Open Source Technology Center


Re: futex: Allow FUTEX_CLOCK_REALTIME with FUTEX_WAIT op

2016-06-22 Thread Darren Hart
On Mon, Jun 20, 2016 at 04:26:52PM +0200, Matthieu CASTET wrote:
> Hi,
> 
> the commit 337f13046ff03717a9e99675284a817527440a49 is saying that it
> change to syscall to an equivalent to FUTEX_WAIT_BITSET |
> FUTEX_CLOCK_REALTIME with a bitset of FUTEX_BITSET_MATCH_ANY.
> 
> It seems wrong to me, because in case of FUTEX_WAIT, in
> "SYSCALL_DEFINE6(futex", we convert relative timeout to absolute
> timeout [1].
> 
> So FUTEX_CLOCK_REALTIME | FUTEX_WAIT is expecting a relative timeout
> when FUTEX_WAIT_BITSET take an absolute timeout.
> 
> To make it work you have to use something like the (untested) attached
> patch.

+Eric Dumazet

Thanks for reporting Matthieu,

FUTEX_WAIT traditionally used a relative timeout with CLOCK_MONOTONIC while
FUTEX_WAIT_BITSET could use either ??? based on the FUTEX_CLOCK_ flag used. The
man page is not particularly clear on this:

http://man7.org/linux/man-pages/man2/futex.2.html

"
The FUTEX_WAIT_BITSET operation also interprets the timeout argument
differently from FUTEX_WAIT.  See the discussion of FUTEX_CLOCK_REALTIME,
above.
"

Matthew Kerrisk:
I think this language could be removed now that we support the
FUTEX_CLOCK_REALTIME flag for both futex ops.

As for the intended behavior of the FUTEX_CLOCK_REALTIME flag:


FUTEX_CLOCK_REALTIME (since Linux 2.6.28)
This option bit can be employed only with the FUTEX_WAIT_BITSET,
FUTEX_WAIT_REQUEUE_PI, and FUTEX_WAIT (since Linux 4.5) operations.

(NOTE: FUTEX_WAIT was recently added after the patch in question here)

If this option is set, the kernel treats timeout as an absolute time based
on CLOCK_REALTIME.

If this option is not set, the kernel treats timeout as a relative time,
measured against the CLOCK_MONOTONIC clock.


This supports your argument Matthieu. The assumption of a relative timeout for
FUTEX_WAIT in SYSCALL_DEFINE6 needs to be updated to account for FUTEX_WAIT now
honoring the FUTEX_CLOCK_REALTIME flag, which treats the timeout as absolute.

However, I don't think the patch below is correct. The existing logic
determines the type of timeout based on the futex_op when it should instead
determine the type of timeout based on the FUTEX_CLOCK_REALTIME flag.

My reading of the man page is that FUTEX_WAIT_BITSET abides by the timeout
interpretation defined by the FUTEX_CLOCK_REALTIME attribute, so
SYSCALL_DEFINE6 was misbehaving for FUTEX_WAIT|FUTEX_CLOCK_REALTIME (where the
timeout should have been treated as absolute) as well as for
FUTEX_WAIT_BITSET|FUTEX_CLOCK_MONOTONIC (where the timeout should have been
treated as relative).

Consider the following:

diff --git a/kernel/futex.c b/kernel/futex.c
index 33664f7..fa2af29 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -3230,7 +3230,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, 
val,
return -EINVAL;
 
t = timespec_to_ktime(ts);
-   if (cmd == FUTEX_WAIT)
+   if (!(cmd & FUTEX_CLOCK_REALTIME))
t = ktime_add_safe(ktime_get(), t);
tp = 
}

The concern for me is whether the code is incorrect, or if the man page is
incorrect. Does existing userspace code expect the FUTEX_WAIT_BITSET op to
always use an absolute timeout, regardless of the CLOCK used?





> 
> Matthieu
> 
> [1]
> if (cmd == FUTEX_WAIT)
> t = ktime_add_safe(ktime_get(), t);

> diff --git a/kernel/futex.c b/kernel/futex.c
> index 33664f7..4bee915 100644
> --- a/kernel/futex.c
> +++ b/kernel/futex.c
> @@ -3230,7 +3230,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, 
> u32, val,
>   return -EINVAL;
>  
>   t = timespec_to_ktime(ts);
> - if (cmd == FUTEX_WAIT)
> + if (cmd == FUTEX_WAIT && !(op & FUTEX_CLOCK_REALTIME))
>   t = ktime_add_safe(ktime_get(), t);
>   tp = 
>   }


-- 
Darren Hart
Intel Open Source Technology Center


  1   2   3   4   5   6   7   8   9   10   >