Re: [PATCH v1 1/1] ipv4: Prevent malformed UFO fragments in ip_append_page

2016-06-14 Thread David Miller
From: Steven Caron 
Date: Mon, 13 Jun 2016 14:01:19 +

> As  the ip fragment offset field counts 8-byte chunks, non-final ip
> fragments must be multiples of 8 bytes of payload. Depending  on the
> mtu and ip option sizes, ip_append_page wasn't respecting this,
> notably when running NFS under UDP.
> 
> Signed-off-by: Steven Caron 

This seems to have DOS newlines or something strange like that.

Please fix your email client to send clean patches.

Thanks.


Re: [PATCH v1 1/1] ipv4: Prevent malformed UFO fragments in ip_append_page

2016-06-14 Thread David Miller
From: Steven Caron 
Date: Mon, 13 Jun 2016 14:01:19 +

> As  the ip fragment offset field counts 8-byte chunks, non-final ip
> fragments must be multiples of 8 bytes of payload. Depending  on the
> mtu and ip option sizes, ip_append_page wasn't respecting this,
> notably when running NFS under UDP.
> 
> Signed-off-by: Steven Caron 

This seems to have DOS newlines or something strange like that.

Please fix your email client to send clean patches.

Thanks.


[PATCH v2 2/3] serial: 8250_dma: Export serial8250_rx_dma_flush()

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

Export serial8250_rx_dma_flush() for use by SOC UART drivers.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/tty/serial/8250/8250_dma.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/tty/serial/8250/8250_dma.c 
b/drivers/tty/serial/8250/8250_dma.c
index 7f33d1c..3590d01 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -145,6 +145,7 @@ void serial8250_rx_dma_flush(struct uart_8250_port *p)
dmaengine_terminate_all(dma->rxchan);
}
 }
+EXPORT_SYMBOL_GPL(serial8250_rx_dma_flush);
 
 int serial8250_request_dma(struct uart_8250_port *p)
 {
-- 
1.9.1



[PATCH v2 1/3] dmaengine: hsu: Export hsu_dma_get_status()

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

To allow other code to safely read DMA Channel Status Register (where
the register attribute for Channel Error, Descriptor Time Out &
Descriptor Done fields are read-clear), export hsu_dma_get_status().
hsu_dma_irq() is renamed to hsu_dma_do_irq() and requires Status
Register value to be passed in.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_mid.c | 22 +++---
 include/linux/dma/hsu.h| 14 --
 4 files changed, 106 insertions(+), 31 deletions(-)

diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c
index f8c5cd5..c5f21ef 100644
--- a/drivers/dma/hsu/hsu.c
+++ b/drivers/dma/hsu/hsu.c
@@ -126,28 +126,33 @@ static void hsu_dma_start_transfer(struct hsu_dma_chan 
*hsuc)
hsu_dma_start_channel(hsuc);
 }
 
-static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc)
-{
-   unsigned long flags;
-   u32 sr;
-
-   spin_lock_irqsave(>vchan.lock, flags);
-   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
-   spin_unlock_irqrestore(>vchan.lock, flags);
-
-   return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
-}
-
-irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
+/*
+ *  hsu_dma_get_status() - get DMA channel status
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: pointer for DMA Channel Status Register value
+ *
+ *  Description:
+ *  The function reads and clears the DMA Channel Status Register, checks
+ *  if it was a timeout interrupt and returns a corresponding value.
+ *
+ *  Caller should provide a valid pointer for the DMA Channel Status
+ *  Register value that will be returned in @status.
+ *
+ *  Return:
+ *  1 for DMA timeout status, 0 for other DMA status, or error code for
+ *  invalid parameters or no interrupt pending.
+ */
+int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 *status)
 {
struct hsu_dma_chan *hsuc;
-   struct hsu_dma_desc *desc;
unsigned long flags;
u32 sr;
 
/* Sanity check */
if (nr >= chip->hsu->nr_channels)
-   return IRQ_NONE;
+   return -EINVAL;
 
hsuc = >hsu->chan[nr];
 
@@ -155,22 +160,65 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, 
unsigned short nr)
 * No matter what situation, need read clear the IRQ status
 * There is a bug, see Errata 5, HSD 2900918
 */
-   sr = hsu_dma_chan_get_sr(hsuc);
+   spin_lock_irqsave(>vchan.lock, flags);
+   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
+   spin_unlock_irqrestore(>vchan.lock, flags);
+
+   /* Check if any interrupt is pending */
+   sr &= ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
if (!sr)
-   return IRQ_NONE;
+   return -EIO;
 
/* Timeout IRQ, need wait some time, see Errata 2 */
if (sr & HSU_CH_SR_DESCTO_ANY)
udelay(2);
 
+   /*
+* At this point, at least one of Descriptor Time Out, Channel Error
+* or Descriptor Done bits must be set. Clear the Descriptor Time Out
+* bits and if sr is still non-zero, it must be channel error or
+* descriptor done which are higher priority than timeout and handled
+* in hsu_dma_do_irq(). Else, it must be a timeout.
+*/
sr &= ~HSU_CH_SR_DESCTO_ANY;
-   if (!sr)
-   return IRQ_HANDLED;
+
+   *status = sr;
+
+   return sr ? 0 : 1;
+}
+EXPORT_SYMBOL_GPL(hsu_dma_get_status);
+
+/*
+ *  hsu_dma_do_irq() - DMA interrupt handler
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: Channel Status Register value
+ *
+ *  Description:
+ *  This function handles Channel Error and Descriptor Done interrupts.
+ *  This function should be called after determining that the DMA interrupt
+ *  is not a normal timeout interrupt, ie. hsu_dma_get_status() returned 0.
+ *
+ *  Return:
+ *  IRQ_NONE for invalid channel number, IRQ_HANDLED otherwise.
+ */
+irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 status)
+{
+   struct hsu_dma_chan *hsuc;
+   struct hsu_dma_desc *desc;
+   unsigned long flags;
+
+   /* Sanity check */
+   if (nr >= chip->hsu->nr_channels)
+   return IRQ_NONE;
+
+   hsuc = >hsu->chan[nr];
 
spin_lock_irqsave(>vchan.lock, flags);
desc = hsuc->desc;
if (desc) {
-   if (sr & HSU_CH_SR_CHE) {
+   if (status & HSU_CH_SR_CHE) {
desc->status = DMA_ERROR;
} else if (desc->active < desc->nents) {
hsu_dma_start_channel(hsuc);
@@ -184,7 +232,7 @@ irqreturn_t 

[PATCH v2 2/3] serial: 8250_dma: Export serial8250_rx_dma_flush()

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

Export serial8250_rx_dma_flush() for use by SOC UART drivers.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/tty/serial/8250/8250_dma.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/tty/serial/8250/8250_dma.c 
b/drivers/tty/serial/8250/8250_dma.c
index 7f33d1c..3590d01 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -145,6 +145,7 @@ void serial8250_rx_dma_flush(struct uart_8250_port *p)
dmaengine_terminate_all(dma->rxchan);
}
 }
+EXPORT_SYMBOL_GPL(serial8250_rx_dma_flush);
 
 int serial8250_request_dma(struct uart_8250_port *p)
 {
-- 
1.9.1



[PATCH v2 1/3] dmaengine: hsu: Export hsu_dma_get_status()

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

To allow other code to safely read DMA Channel Status Register (where
the register attribute for Channel Error, Descriptor Time Out &
Descriptor Done fields are read-clear), export hsu_dma_get_status().
hsu_dma_irq() is renamed to hsu_dma_do_irq() and requires Status
Register value to be passed in.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_mid.c | 22 +++---
 include/linux/dma/hsu.h| 14 --
 4 files changed, 106 insertions(+), 31 deletions(-)

diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c
index f8c5cd5..c5f21ef 100644
--- a/drivers/dma/hsu/hsu.c
+++ b/drivers/dma/hsu/hsu.c
@@ -126,28 +126,33 @@ static void hsu_dma_start_transfer(struct hsu_dma_chan 
*hsuc)
hsu_dma_start_channel(hsuc);
 }
 
-static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc)
-{
-   unsigned long flags;
-   u32 sr;
-
-   spin_lock_irqsave(>vchan.lock, flags);
-   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
-   spin_unlock_irqrestore(>vchan.lock, flags);
-
-   return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
-}
-
-irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
+/*
+ *  hsu_dma_get_status() - get DMA channel status
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: pointer for DMA Channel Status Register value
+ *
+ *  Description:
+ *  The function reads and clears the DMA Channel Status Register, checks
+ *  if it was a timeout interrupt and returns a corresponding value.
+ *
+ *  Caller should provide a valid pointer for the DMA Channel Status
+ *  Register value that will be returned in @status.
+ *
+ *  Return:
+ *  1 for DMA timeout status, 0 for other DMA status, or error code for
+ *  invalid parameters or no interrupt pending.
+ */
+int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 *status)
 {
struct hsu_dma_chan *hsuc;
-   struct hsu_dma_desc *desc;
unsigned long flags;
u32 sr;
 
/* Sanity check */
if (nr >= chip->hsu->nr_channels)
-   return IRQ_NONE;
+   return -EINVAL;
 
hsuc = >hsu->chan[nr];
 
@@ -155,22 +160,65 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, 
unsigned short nr)
 * No matter what situation, need read clear the IRQ status
 * There is a bug, see Errata 5, HSD 2900918
 */
-   sr = hsu_dma_chan_get_sr(hsuc);
+   spin_lock_irqsave(>vchan.lock, flags);
+   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
+   spin_unlock_irqrestore(>vchan.lock, flags);
+
+   /* Check if any interrupt is pending */
+   sr &= ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
if (!sr)
-   return IRQ_NONE;
+   return -EIO;
 
/* Timeout IRQ, need wait some time, see Errata 2 */
if (sr & HSU_CH_SR_DESCTO_ANY)
udelay(2);
 
+   /*
+* At this point, at least one of Descriptor Time Out, Channel Error
+* or Descriptor Done bits must be set. Clear the Descriptor Time Out
+* bits and if sr is still non-zero, it must be channel error or
+* descriptor done which are higher priority than timeout and handled
+* in hsu_dma_do_irq(). Else, it must be a timeout.
+*/
sr &= ~HSU_CH_SR_DESCTO_ANY;
-   if (!sr)
-   return IRQ_HANDLED;
+
+   *status = sr;
+
+   return sr ? 0 : 1;
+}
+EXPORT_SYMBOL_GPL(hsu_dma_get_status);
+
+/*
+ *  hsu_dma_do_irq() - DMA interrupt handler
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: Channel Status Register value
+ *
+ *  Description:
+ *  This function handles Channel Error and Descriptor Done interrupts.
+ *  This function should be called after determining that the DMA interrupt
+ *  is not a normal timeout interrupt, ie. hsu_dma_get_status() returned 0.
+ *
+ *  Return:
+ *  IRQ_NONE for invalid channel number, IRQ_HANDLED otherwise.
+ */
+irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 status)
+{
+   struct hsu_dma_chan *hsuc;
+   struct hsu_dma_desc *desc;
+   unsigned long flags;
+
+   /* Sanity check */
+   if (nr >= chip->hsu->nr_channels)
+   return IRQ_NONE;
+
+   hsuc = >hsu->chan[nr];
 
spin_lock_irqsave(>vchan.lock, flags);
desc = hsuc->desc;
if (desc) {
-   if (sr & HSU_CH_SR_CHE) {
+   if (status & HSU_CH_SR_CHE) {
desc->status = DMA_ERROR;
} else if (desc->active < desc->nents) {
hsu_dma_start_channel(hsuc);
@@ -184,7 +232,7 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned 
short nr)
 
   

[PATCH v2 3/3] serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

In DNV, when RX DMA is used and number of bytes received is less than
transfer size, only RX DMA timeout interrupt is sent. When this happens,
read the RX buffer.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/tty/serial/8250/8250_mid.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mid.c 
b/drivers/tty/serial/8250/8250_mid.c
index b218ff5..339de9c 100644
--- a/drivers/tty/serial/8250/8250_mid.c
+++ b/drivers/tty/serial/8250/8250_mid.c
@@ -96,6 +96,7 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
 static int dnv_handle_irq(struct uart_port *p)
 {
struct mid8250 *mid = p->private_data;
+   struct uart_8250_port *up = up_to_u8250p(p);
unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
u32 status;
int ret = IRQ_NONE;
@@ -103,9 +104,10 @@ static int dnv_handle_irq(struct uart_port *p)
 
if (fisr & BIT(2)) {
err = hsu_dma_get_status(>dma_chip, 1, );
-   if (err > 0)
+   if (err > 0) {
+   serial8250_rx_dma_flush(up);
ret |= IRQ_HANDLED;
-   else if (err == 0)
+   } else if (err == 0)
ret |= hsu_dma_do_irq(>dma_chip, 1, status);
}
if (fisr & BIT(1)) {
-- 
1.9.1



[PATCH v2 0/3] Fix DNV HSUART RX DMA timeout interrupt issue

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

These patches fix a DNV HSUART DMA issue with timeout interrupts, where
RX data is stuck in buffer when RX DMA is used and the number of received
bytes is less than 4096.
These patches have been tested on Intel Denverton platform.

Changes from v1:
  - Added patch "serial: 8250_dma: Export serial8250_rx_dma_flush()" to solve
build error when CONFIG_SERIAL_8250_MID is set to "m".

Chuah, Kim Tatt (3):
  dmaengine: hsu: Export hsu_dma_get_status()
  serial: 8250_dma: Export serial8250_rx_dma_flush()
  serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_dma.c |  1 +
 drivers/tty/serial/8250/8250_mid.c | 24 +++---
 include/linux/dma/hsu.h| 14 --
 5 files changed, 109 insertions(+), 31 deletions(-)

-- 
1.9.1



[PATCH v2 3/3] serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

In DNV, when RX DMA is used and number of bytes received is less than
transfer size, only RX DMA timeout interrupt is sent. When this happens,
read the RX buffer.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/tty/serial/8250/8250_mid.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mid.c 
b/drivers/tty/serial/8250/8250_mid.c
index b218ff5..339de9c 100644
--- a/drivers/tty/serial/8250/8250_mid.c
+++ b/drivers/tty/serial/8250/8250_mid.c
@@ -96,6 +96,7 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
 static int dnv_handle_irq(struct uart_port *p)
 {
struct mid8250 *mid = p->private_data;
+   struct uart_8250_port *up = up_to_u8250p(p);
unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
u32 status;
int ret = IRQ_NONE;
@@ -103,9 +104,10 @@ static int dnv_handle_irq(struct uart_port *p)
 
if (fisr & BIT(2)) {
err = hsu_dma_get_status(>dma_chip, 1, );
-   if (err > 0)
+   if (err > 0) {
+   serial8250_rx_dma_flush(up);
ret |= IRQ_HANDLED;
-   else if (err == 0)
+   } else if (err == 0)
ret |= hsu_dma_do_irq(>dma_chip, 1, status);
}
if (fisr & BIT(1)) {
-- 
1.9.1



[PATCH v2 0/3] Fix DNV HSUART RX DMA timeout interrupt issue

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

These patches fix a DNV HSUART DMA issue with timeout interrupts, where
RX data is stuck in buffer when RX DMA is used and the number of received
bytes is less than 4096.
These patches have been tested on Intel Denverton platform.

Changes from v1:
  - Added patch "serial: 8250_dma: Export serial8250_rx_dma_flush()" to solve
build error when CONFIG_SERIAL_8250_MID is set to "m".

Chuah, Kim Tatt (3):
  dmaengine: hsu: Export hsu_dma_get_status()
  serial: 8250_dma: Export serial8250_rx_dma_flush()
  serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_dma.c |  1 +
 drivers/tty/serial/8250/8250_mid.c | 24 +++---
 include/linux/dma/hsu.h| 14 --
 5 files changed, 109 insertions(+), 31 deletions(-)

-- 
1.9.1



Re: [patch net-next] net: hns: add skb_reset_mac_header() after skb being alloc

2016-06-14 Thread David Miller
From: Yisen Zhuang 
Date: Mon, 13 Jun 2016 20:41:22 +0800

> From: Kejian Yan 
> 
> HNS receives a packet without doing anything, but it should call
> skb_reset_mac_header() to initialize the header before using
> eth_hdr().
> 
> Fixes: 0d6b425a3773c3445b0f51b2f333821beaacb619
> Signed-off-by: Kejian Yan 
> Signed-off-by: Yisen Zhuang 

Well, this patch made me look at this function.

You really shouldn't be filtering packets looped back, that is
the stack's job.  It shouldn't be happening in the driver.

And once you remove that code, this patch here is no longer
necessary.

Second of all, unless you card supports every protocol that
exists in the past, present, and _future_ you cannot set
skb->ip_summed to CHECKSUM_UNNECSSARY unconditionally like
that.

You can only set that for protocols your chip actually supports.


Re: [patch net-next] net: hns: add skb_reset_mac_header() after skb being alloc

2016-06-14 Thread David Miller
From: Yisen Zhuang 
Date: Mon, 13 Jun 2016 20:41:22 +0800

> From: Kejian Yan 
> 
> HNS receives a packet without doing anything, but it should call
> skb_reset_mac_header() to initialize the header before using
> eth_hdr().
> 
> Fixes: 0d6b425a3773c3445b0f51b2f333821beaacb619
> Signed-off-by: Kejian Yan 
> Signed-off-by: Yisen Zhuang 

Well, this patch made me look at this function.

You really shouldn't be filtering packets looped back, that is
the stack's job.  It shouldn't be happening in the driver.

And once you remove that code, this patch here is no longer
necessary.

Second of all, unless you card supports every protocol that
exists in the past, present, and _future_ you cannot set
skb->ip_summed to CHECKSUM_UNNECSSARY unconditionally like
that.

You can only set that for protocols your chip actually supports.


Re: [v6, 07/11] powerpc/powernv: set power_save func after the idle states are initialized

2016-06-14 Thread Michael Ellerman
On Wed, 2016-08-06 at 16:54:27 UTC, "Shreyas B. Prabhu" wrote:
> pnv_init_idle_states discovers supported idle states from the
> device tree and does the required initialization. Set power_save
> function pointer only after this initialization is done

This looks like a bug fix? Or is this not a concern in practice for some reason
(and if so what is that reason)?

cheers


Re: [v6, 07/11] powerpc/powernv: set power_save func after the idle states are initialized

2016-06-14 Thread Michael Ellerman
On Wed, 2016-08-06 at 16:54:27 UTC, "Shreyas B. Prabhu" wrote:
> pnv_init_idle_states discovers supported idle states from the
> device tree and does the required initialization. Set power_save
> function pointer only after this initialization is done

This looks like a bug fix? Or is this not a concern in practice for some reason
(and if so what is that reason)?

cheers


[PATCH v2] staging: gdm724x: Replace semaphore netlink with mutex

2016-06-14 Thread Binoy Jayan
Replace semaphore netlink_mutex with mutex. Semaphores are
going away in the future.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/gdm724x/netlink_k.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/staging/gdm724x/netlink_k.c 
b/drivers/staging/gdm724x/netlink_k.c
index a0232e8..abe2425 100644
--- a/drivers/staging/gdm724x/netlink_k.c
+++ b/drivers/staging/gdm724x/netlink_k.c
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -21,13 +22,7 @@
 
 #include "netlink_k.h"
 
-#if defined(DEFINE_MUTEX)
 static DEFINE_MUTEX(netlink_mutex);
-#else
-static struct semaphore netlink_mutex;
-#define mutex_lock(x)  down(x)
-#define mutex_unlock(x)up(x)
-#endif
 
 #define ND_MAX_GROUP   30
 #define ND_IFINDEX_LEN sizeof(int)
@@ -96,10 +91,6 @@ struct sock *netlink_init(int unit,
.input  = netlink_rcv,
};
 
-#if !defined(DEFINE_MUTEX)
-   init_MUTEX(_mutex);
-#endif
-
sock = netlink_kernel_create(_net, unit, );
 
if (sock)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2] staging: gdm724x: Replace semaphore netlink with mutex

2016-06-14 Thread Binoy Jayan
Replace semaphore netlink_mutex with mutex. Semaphores are
going away in the future.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/gdm724x/netlink_k.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/staging/gdm724x/netlink_k.c 
b/drivers/staging/gdm724x/netlink_k.c
index a0232e8..abe2425 100644
--- a/drivers/staging/gdm724x/netlink_k.c
+++ b/drivers/staging/gdm724x/netlink_k.c
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -21,13 +22,7 @@
 
 #include "netlink_k.h"
 
-#if defined(DEFINE_MUTEX)
 static DEFINE_MUTEX(netlink_mutex);
-#else
-static struct semaphore netlink_mutex;
-#define mutex_lock(x)  down(x)
-#define mutex_unlock(x)up(x)
-#endif
 
 #define ND_MAX_GROUP   30
 #define ND_IFINDEX_LEN sizeof(int)
@@ -96,10 +91,6 @@ struct sock *netlink_init(int unit,
.input  = netlink_rcv,
};
 
-#if !defined(DEFINE_MUTEX)
-   init_MUTEX(_mutex);
-#endif
-
sock = netlink_kernel_create(_net, unit, );
 
if (sock)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH] sound: aedsp16: Change structure initialisation to C99 style

2016-06-14 Thread Takashi Iwai
On Wed, 15 Jun 2016 05:53:23 +0200,
Amitoj Kaur Chawla wrote:
> 
> Replace the in order struct initialisation style with explicit field
> style.
> 
> The Coccinelle semantic patch used to make this change is as follows:
> 
> @decl@
> identifier i1,fld;
> type T;
> field list[n] fs;
> @@
> 
> struct i1 {
>  fs
>  T fld;
>  ...};
> 
> @@
> identifier decl.i1,i2,decl.fld;
> expression e;
> position bad.p, bad.fix;
> @@
> 
> struct i1 i2@p = { ...,
> + .fld = e
> - e@fix
>  ,...};
> 
> Signed-off-by: Amitoj Kaur Chawla 

Applied, thanks.


Takashi


Re: [PATCH] sound: aedsp16: Change structure initialisation to C99 style

2016-06-14 Thread Takashi Iwai
On Wed, 15 Jun 2016 05:53:23 +0200,
Amitoj Kaur Chawla wrote:
> 
> Replace the in order struct initialisation style with explicit field
> style.
> 
> The Coccinelle semantic patch used to make this change is as follows:
> 
> @decl@
> identifier i1,fld;
> type T;
> field list[n] fs;
> @@
> 
> struct i1 {
>  fs
>  T fld;
>  ...};
> 
> @@
> identifier decl.i1,i2,decl.fld;
> expression e;
> position bad.p, bad.fix;
> @@
> 
> struct i1 i2@p = { ...,
> + .fld = e
> - e@fix
>  ,...};
> 
> Signed-off-by: Amitoj Kaur Chawla 

Applied, thanks.


Takashi


Re: [PATCH net-next 0/3] r8152: code adjustment for PHY

2016-06-14 Thread David Miller
From: Hayes Wang 
Date: Mon, 13 Jun 2016 17:49:35 +0800

> These patches are for adjusting the code about PHY and setting speed.

Series applied, thanks.


Re: [v6, 03/11] powerpc/powernv: Rename idle_power7.S to idle_power_common.S

2016-06-14 Thread Michael Ellerman
On Wed, 2016-08-06 at 16:54:23 UTC, "Shreyas B. Prabhu" wrote:
> idle_power7.S handles idle entry/exit for POWER7, POWER8 and in next
> patch for POWER9. Rename the file to a non-hardware specific
> name.

It's not common for all powerpc CPUs though. So can you call it something other
than just "common".

Maybe idle_book3s.S, or (if it's correct) idle_206.S

cheers


Re: [PATCH net-next 0/3] r8152: code adjustment for PHY

2016-06-14 Thread David Miller
From: Hayes Wang 
Date: Mon, 13 Jun 2016 17:49:35 +0800

> These patches are for adjusting the code about PHY and setting speed.

Series applied, thanks.


Re: [v6, 03/11] powerpc/powernv: Rename idle_power7.S to idle_power_common.S

2016-06-14 Thread Michael Ellerman
On Wed, 2016-08-06 at 16:54:23 UTC, "Shreyas B. Prabhu" wrote:
> idle_power7.S handles idle entry/exit for POWER7, POWER8 and in next
> patch for POWER9. Rename the file to a non-hardware specific
> name.

It's not common for all powerpc CPUs though. So can you call it something other
than just "common".

Maybe idle_book3s.S, or (if it's correct) idle_206.S

cheers


[PATCH] RTC: Add functionality to read/write rtc scratch registers

2016-06-14 Thread Keerthy
From: Russ Dill  

Many RTCs provide scratch registers that are maintained so long as the RTC
has power. Provide a generic method to access these registers.

Signed-off-by: Russ Dill 
Signed-off-by: Keerthy 
---
 drivers/rtc/interface.c | 50 +
 drivers/rtc/rtc-omap.c  | 35 ++
 include/linux/rtc.h |  7 +++
 3 files changed, 92 insertions(+)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 7cafd4d..d5a7ee2 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -1018,3 +1018,53 @@ int rtc_set_offset(struct rtc_device *rtc, long offset)
mutex_unlock(>ops_lock);
return ret;
 }
+
+/* rtc_read_scratch - Read from RTC scratch register
+ * @ rtc: rtc device to be used
+ * @ index: index of scratch register
+ * @ value: returned value read
+ *
+ * Kernel interface read from an RTC scratch register
+ */
+int rtc_read_scratch(struct rtc_device *rtc, unsigned int index, u32 *value)
+{
+   int err;
+
+   mutex_lock(>ops_lock);
+   if (!rtc->ops)
+   err = -ENODEV;
+   else if (index >= rtc->ops->scratch_size || !rtc->ops->read_scratch)
+   err = -EINVAL;
+   else
+   err = rtc->ops->read_scratch(rtc->dev.parent, index, value);
+   mutex_unlock(>ops_lock);
+   return err;
+}
+EXPORT_SYMBOL_GPL(rtc_read_scratch);
+
+/* rtc_write_scratch - Write to RTC scratch register
+ * @ rtc: rtc device to be used
+ * @ index: index of scratch register
+ * @ value: value to write
+ *
+ * Kernel interface write to an RTC scratch register
+ */
+int rtc_write_scratch(struct rtc_device *rtc, unsigned int index, u32 value)
+{
+   int err;
+
+   mutex_lock(>ops_lock);
+
+   if (!rtc->ops)
+   err = -ENODEV;
+   else if (index >= rtc->ops->scratch_size ||
+!rtc->ops->write_scratch)
+   err = -EINVAL;
+   else
+   err = rtc->ops->write_scratch(rtc->dev.parent, index, value);
+
+   mutex_unlock(>ops_lock);
+
+   return err;
+}
+EXPORT_SYMBOL_GPL(rtc_write_scratch);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index ec2e9c5..d00ca11 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -66,6 +66,10 @@
 #define OMAP_RTC_COMP_MSB_REG  0x50
 #define OMAP_RTC_OSC_REG   0x54
 
+#define OMAP_RTC_SCRATCH0_REG  0x60
+#define OMAP_RTC_SCRATCH1_REG  0x64
+#define OMAP_RTC_SCRATCH2_REG  0x68
+
 #define OMAP_RTC_KICK0_REG 0x6c
 #define OMAP_RTC_KICK1_REG 0x70
 
@@ -405,6 +409,34 @@ static int omap_rtc_set_alarm(struct device *dev, struct 
rtc_wkalrm *alm)
 
 static struct omap_rtc *omap_rtc_power_off_rtc;
 
+static const u32 omap_rtc_scratch_regs[] = {
+   OMAP_RTC_SCRATCH0_REG,
+   OMAP_RTC_SCRATCH1_REG,
+   OMAP_RTC_SCRATCH2_REG,
+};
+
+static int omap_rtc_read_scratch(struct device *dev, unsigned int index,
+u32 *value)
+{
+   *value = readl(omap_rtc_power_off_rtc->base +
+  omap_rtc_scratch_regs[index]);
+
+   return 0;
+}
+
+static int omap_rtc_write_scratch(struct device *dev, unsigned int index,
+ u32 value)
+{
+   struct omap_rtc *rtc = dev_get_drvdata(dev);
+
+   rtc->type->unlock(rtc);
+   writel(value, omap_rtc_power_off_rtc->base +
+  omap_rtc_scratch_regs[index]);
+   rtc->type->lock(rtc);
+
+   return 0;
+}
+
 /*
  * omap_rtc_poweroff: RTC-controlled power off
  *
@@ -475,6 +507,9 @@ static struct rtc_class_ops omap_rtc_ops = {
.read_alarm = omap_rtc_read_alarm,
.set_alarm  = omap_rtc_set_alarm,
.alarm_irq_enable = omap_rtc_alarm_irq_enable,
+   .read_scratch   = omap_rtc_read_scratch,
+   .write_scratch  = omap_rtc_write_scratch,
+   .scratch_size   = ARRAY_SIZE(omap_rtc_scratch_regs),
 };
 
 static const struct omap_rtc_device_type omap_rtc_default_type = {
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index b693ada..da5e003 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -91,6 +91,10 @@ struct rtc_class_ops {
int (*alarm_irq_enable)(struct device *, unsigned int enabled);
int (*read_offset)(struct device *, long *offset);
int (*set_offset)(struct device *, long offset);
+   int (*read_scratch)(struct device *, unsigned int, u32*);
+   int (*write_scratch)(struct device *, unsigned int, u32);
+
+   unsigned int scratch_size;
 };
 
 #define RTC_DEVICE_NAME_SIZE 20
@@ -214,6 +218,9 @@ int rtc_read_offset(struct rtc_device *rtc, long *offset);
 int rtc_set_offset(struct rtc_device *rtc, long offset);
 void rtc_timer_do_work(struct work_struct *work);
 
+int rtc_read_scratch(struct rtc_device *rtc, unsigned int index, u32 *value);
+int rtc_write_scratch(struct rtc_device *rtc, 

[PATCH] RTC: Add functionality to read/write rtc scratch registers

2016-06-14 Thread Keerthy
From: Russ Dill  

Many RTCs provide scratch registers that are maintained so long as the RTC
has power. Provide a generic method to access these registers.

Signed-off-by: Russ Dill 
Signed-off-by: Keerthy 
---
 drivers/rtc/interface.c | 50 +
 drivers/rtc/rtc-omap.c  | 35 ++
 include/linux/rtc.h |  7 +++
 3 files changed, 92 insertions(+)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 7cafd4d..d5a7ee2 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -1018,3 +1018,53 @@ int rtc_set_offset(struct rtc_device *rtc, long offset)
mutex_unlock(>ops_lock);
return ret;
 }
+
+/* rtc_read_scratch - Read from RTC scratch register
+ * @ rtc: rtc device to be used
+ * @ index: index of scratch register
+ * @ value: returned value read
+ *
+ * Kernel interface read from an RTC scratch register
+ */
+int rtc_read_scratch(struct rtc_device *rtc, unsigned int index, u32 *value)
+{
+   int err;
+
+   mutex_lock(>ops_lock);
+   if (!rtc->ops)
+   err = -ENODEV;
+   else if (index >= rtc->ops->scratch_size || !rtc->ops->read_scratch)
+   err = -EINVAL;
+   else
+   err = rtc->ops->read_scratch(rtc->dev.parent, index, value);
+   mutex_unlock(>ops_lock);
+   return err;
+}
+EXPORT_SYMBOL_GPL(rtc_read_scratch);
+
+/* rtc_write_scratch - Write to RTC scratch register
+ * @ rtc: rtc device to be used
+ * @ index: index of scratch register
+ * @ value: value to write
+ *
+ * Kernel interface write to an RTC scratch register
+ */
+int rtc_write_scratch(struct rtc_device *rtc, unsigned int index, u32 value)
+{
+   int err;
+
+   mutex_lock(>ops_lock);
+
+   if (!rtc->ops)
+   err = -ENODEV;
+   else if (index >= rtc->ops->scratch_size ||
+!rtc->ops->write_scratch)
+   err = -EINVAL;
+   else
+   err = rtc->ops->write_scratch(rtc->dev.parent, index, value);
+
+   mutex_unlock(>ops_lock);
+
+   return err;
+}
+EXPORT_SYMBOL_GPL(rtc_write_scratch);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index ec2e9c5..d00ca11 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -66,6 +66,10 @@
 #define OMAP_RTC_COMP_MSB_REG  0x50
 #define OMAP_RTC_OSC_REG   0x54
 
+#define OMAP_RTC_SCRATCH0_REG  0x60
+#define OMAP_RTC_SCRATCH1_REG  0x64
+#define OMAP_RTC_SCRATCH2_REG  0x68
+
 #define OMAP_RTC_KICK0_REG 0x6c
 #define OMAP_RTC_KICK1_REG 0x70
 
@@ -405,6 +409,34 @@ static int omap_rtc_set_alarm(struct device *dev, struct 
rtc_wkalrm *alm)
 
 static struct omap_rtc *omap_rtc_power_off_rtc;
 
+static const u32 omap_rtc_scratch_regs[] = {
+   OMAP_RTC_SCRATCH0_REG,
+   OMAP_RTC_SCRATCH1_REG,
+   OMAP_RTC_SCRATCH2_REG,
+};
+
+static int omap_rtc_read_scratch(struct device *dev, unsigned int index,
+u32 *value)
+{
+   *value = readl(omap_rtc_power_off_rtc->base +
+  omap_rtc_scratch_regs[index]);
+
+   return 0;
+}
+
+static int omap_rtc_write_scratch(struct device *dev, unsigned int index,
+ u32 value)
+{
+   struct omap_rtc *rtc = dev_get_drvdata(dev);
+
+   rtc->type->unlock(rtc);
+   writel(value, omap_rtc_power_off_rtc->base +
+  omap_rtc_scratch_regs[index]);
+   rtc->type->lock(rtc);
+
+   return 0;
+}
+
 /*
  * omap_rtc_poweroff: RTC-controlled power off
  *
@@ -475,6 +507,9 @@ static struct rtc_class_ops omap_rtc_ops = {
.read_alarm = omap_rtc_read_alarm,
.set_alarm  = omap_rtc_set_alarm,
.alarm_irq_enable = omap_rtc_alarm_irq_enable,
+   .read_scratch   = omap_rtc_read_scratch,
+   .write_scratch  = omap_rtc_write_scratch,
+   .scratch_size   = ARRAY_SIZE(omap_rtc_scratch_regs),
 };
 
 static const struct omap_rtc_device_type omap_rtc_default_type = {
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index b693ada..da5e003 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -91,6 +91,10 @@ struct rtc_class_ops {
int (*alarm_irq_enable)(struct device *, unsigned int enabled);
int (*read_offset)(struct device *, long *offset);
int (*set_offset)(struct device *, long offset);
+   int (*read_scratch)(struct device *, unsigned int, u32*);
+   int (*write_scratch)(struct device *, unsigned int, u32);
+
+   unsigned int scratch_size;
 };
 
 #define RTC_DEVICE_NAME_SIZE 20
@@ -214,6 +218,9 @@ int rtc_read_offset(struct rtc_device *rtc, long *offset);
 int rtc_set_offset(struct rtc_device *rtc, long offset);
 void rtc_timer_do_work(struct work_struct *work);
 
+int rtc_read_scratch(struct rtc_device *rtc, unsigned int index, u32 *value);
+int rtc_write_scratch(struct rtc_device *rtc, unsigned int index, u32 value);
+
 static inline bool 

[PATCH v3 2/5] staging: wilc1000: Replace semaphore txq_add_to_head_cs with mutex

2016-06-14 Thread Binoy Jayan
The semaphore 'txq_add_to_head_cs' is a simple mutex, so it should be
written as one. Semaphores are going away in the future. Also, removing
the timeout scenario as the error handling code does not propagate the
timeout properly.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/wilc1000/linux_wlan.c |  4 ++--
 drivers/staging/wilc1000/wilc_wfi_netdevice.h |  3 ++-
 drivers/staging/wilc1000/wilc_wlan.c  | 11 ---
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 90f906d..a933551 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -20,7 +20,7 @@
 #include 
 #include 
 #include 
-
+#include 
 #include 
 #include 
 
@@ -679,7 +679,7 @@ static int wlan_init_locks(struct net_device *dev)
mutex_init(>rxq_cs);
 
spin_lock_init(>txq_spinlock);
-   sema_init(>txq_add_to_head_cs, 1);
+   mutex_init(>txq_add_to_head_cs);
 
init_completion(>txq_event);
 
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 12d7c7b..239cd43 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -43,6 +43,7 @@
 #include "wilc_wlan.h"
 #include 
 #include 
+#include 
 
 #define FLOW_CONTROL_LOWER_THRESHOLD   128
 #define FLOW_CONTROL_UPPER_THRESHOLD   256
@@ -171,7 +172,7 @@ struct wilc {
struct wilc_vif *vif[NUM_CONCURRENT_IFC];
u8 open_ifcs;
 
-   struct semaphore txq_add_to_head_cs;
+   struct mutex txq_add_to_head_cs;
spinlock_t txq_spinlock;
 
struct mutex rxq_cs;
diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 1a57135..9afbe8d 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -99,9 +99,7 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
unsigned long flags;
struct wilc *wilc = vif->wilc;
 
-   if (wilc_lock_timeout(wilc, >txq_add_to_head_cs,
-   CFG_PKTS_TIMEOUT))
-   return -1;
+   mutex_lock(>txq_add_to_head_cs);
 
spin_lock_irqsave(>txq_spinlock, flags);
 
@@ -119,7 +117,7 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
wilc->txq_entries += 1;
 
spin_unlock_irqrestore(>txq_spinlock, flags);
-   up(>txq_add_to_head_cs);
+   mutex_unlock(>txq_add_to_head_cs);
complete(>txq_event);
 
return 0;
@@ -573,8 +571,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 
*txq_count)
if (wilc->quit)
break;
 
-   wilc_lock_timeout(wilc, >txq_add_to_head_cs,
-   CFG_PKTS_TIMEOUT);
+   mutex_lock(>txq_add_to_head_cs);
wilc_wlan_txq_filter_dup_tcp_ack(dev);
tqe = wilc_wlan_txq_get_first(wilc);
i = 0;
@@ -755,7 +752,7 @@ _end_:
if (ret != 1)
break;
} while (0);
-   up(>txq_add_to_head_cs);
+   mutex_unlock(>txq_add_to_head_cs);
 
wilc->txq_exit = 1;
*txq_count = wilc->txq_entries;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 3/5] staging: wilc1000: Replace semaphore cfg_event with completion

2016-06-14 Thread Binoy Jayan
The semaphore 'cfg_event' is used as completion, so convert
it to a struct completion type.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/wilc1000/linux_wlan.c |  2 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h |  2 +-
 drivers/staging/wilc1000/wilc_wlan.c  | 15 ---
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index a933551..81a469a 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -683,7 +683,7 @@ static int wlan_init_locks(struct net_device *dev)
 
init_completion(>txq_event);
 
-   sema_init(>cfg_event, 0);
+   init_completion(>cfg_event);
sema_init(>sync_event, 0);
init_completion(>txq_thread_started);
 
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 239cd43..5fbc07c 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -178,7 +178,7 @@ struct wilc {
struct mutex rxq_cs;
struct mutex hif_cs;
 
-   struct semaphore cfg_event;
+   struct completion cfg_event;
struct semaphore sync_event;
struct completion txq_event;
struct completion txq_thread_started;
diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 9afbe8d..19a5809 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -310,7 +310,7 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, 
u8 *buffer,
netdev_dbg(vif->ndev, "Adding config packet ...\n");
if (wilc->quit) {
netdev_dbg(vif->ndev, "Return due to clear function\n");
-   up(>cfg_event);
+   complete(>cfg_event);
return 0;
}
 
@@ -769,7 +769,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc)
 
do {
if (wilc->quit) {
-   up(>cfg_event);
+   complete(>cfg_event);
break;
}
rqe = wilc_wlan_rxq_remove(wilc);
@@ -820,7 +820,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc)
wilc_wlan_cfg_indicate_rx(wilc, 
[pkt_offset + offset], pkt_len, );
if (rsp.type == WILC_CFG_RSP) {
if (wilc->cfg_seq_no == 
rsp.seq_no)
-   up(>cfg_event);
+   
complete(>cfg_event);
} else if (rsp.type == 
WILC_CFG_RSP_STATUS) {
wilc_mac_indicate(wilc, 
WILC_MAC_INDICATE_STATUS);
 
@@ -1228,11 +1228,12 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, 
u16 wid, u8 *buffer,
if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
ret_size = 0;
 
-   if (wilc_lock_timeout(wilc, >cfg_event,
-   CFG_PKTS_TIMEOUT)) {
+   if (!wait_for_completion_timeout(>cfg_event,
+   msecs_to_jiffies(CFG_PKTS_TIMEOUT))) {
netdev_dbg(vif->ndev, "Set Timed Out\n");
ret_size = 0;
}
+
wilc->cfg_frame_in_use = 0;
wilc->cfg_frame_offset = 0;
wilc->cfg_seq_no += 1;
@@ -1265,8 +1266,8 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, 
u16 wid, int commit,
if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
ret_size = 0;
 
-   if (wilc_lock_timeout(wilc, >cfg_event,
-   CFG_PKTS_TIMEOUT)) {
+   if (!wait_for_completion_timeout(>cfg_event,
+   msecs_to_jiffies(CFG_PKTS_TIMEOUT))) {
netdev_dbg(vif->ndev, "Get Timed Out\n");
ret_size = 0;
}
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 4/5] staging: wilc1000: Replace semaphore sync_event with completion

2016-06-14 Thread Binoy Jayan
The semaphore 'sync_event' is used as completion, so convert
it to a struct completion type. Also, return -ETIME if the return
value of wait_for_completion_timeout is 0.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/wilc1000/linux_wlan.c | 10 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 81a469a..39fe350 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -241,7 +241,7 @@ void wilc_mac_indicate(struct wilc *wilc, int flag)
  (unsigned char *), 4);
if (wilc->mac_status == WILC_MAC_STATUS_INIT) {
wilc->mac_status = status;
-   up(>sync_event);
+   complete(>sync_event);
} else {
wilc->mac_status = status;
}
@@ -386,9 +386,9 @@ static int linux_wlan_start_firmware(struct net_device *dev)
if (ret < 0)
return ret;
 
-   ret = wilc_lock_timeout(wilc, >sync_event, 5000);
-   if (ret)
-   return ret;
+   if (!wait_for_completion_timeout(>sync_event,
+   msecs_to_jiffies(5000)))
+   return -ETIME;
 
return 0;
 }
@@ -684,7 +684,7 @@ static int wlan_init_locks(struct net_device *dev)
init_completion(>txq_event);
 
init_completion(>cfg_event);
-   sema_init(>sync_event, 0);
+   init_completion(>sync_event);
init_completion(>txq_thread_started);
 
return 0;
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 5fbc07c..5cc6a82 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -179,7 +179,7 @@ struct wilc {
struct mutex hif_cs;
 
struct completion cfg_event;
-   struct semaphore sync_event;
+   struct completion sync_event;
struct completion txq_event;
struct completion txq_thread_started;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 1/5] staging: wilc1000: Replace semaphore txq_event with completion

2016-06-14 Thread Binoy Jayan
The semaphore 'txq_event' is used as completion, so convert it
to a struct completion type.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/wilc1000/linux_wlan.c | 8 
 drivers/staging/wilc1000/wilc_wfi_netdevice.h | 3 ++-
 drivers/staging/wilc1000/wilc_wlan.c  | 8 +---
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 4f93c11..90f906d 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -316,7 +316,7 @@ static int linux_wlan_txq_task(void *vp)
 
complete(>txq_thread_started);
while (1) {
-   down(>txq_event);
+   wait_for_completion(>txq_event);
 
if (wl->close) {
complete(>txq_thread_started);
@@ -650,7 +650,7 @@ void wilc1000_wlan_deinit(struct net_device *dev)
mutex_unlock(>hif_cs);
}
if (>txq_event)
-   up(>txq_event);
+   wait_for_completion(>txq_event);
 
wlan_deinitialize_threads(dev);
deinit_irq(dev);
@@ -681,7 +681,7 @@ static int wlan_init_locks(struct net_device *dev)
spin_lock_init(>txq_spinlock);
sema_init(>txq_add_to_head_cs, 1);
 
-   sema_init(>txq_event, 0);
+   init_completion(>txq_event);
 
sema_init(>cfg_event, 0);
sema_init(>sync_event, 0);
@@ -738,7 +738,7 @@ static void wlan_deinitialize_threads(struct net_device 
*dev)
wl->close = 1;
 
if (>txq_event)
-   up(>txq_event);
+   complete(>txq_event);
 
if (wl->txq_thread) {
kthread_stop(wl->txq_thread);
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 3a561df6..12d7c7b 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -42,6 +42,7 @@
 #include "host_interface.h"
 #include "wilc_wlan.h"
 #include 
+#include 
 
 #define FLOW_CONTROL_LOWER_THRESHOLD   128
 #define FLOW_CONTROL_UPPER_THRESHOLD   256
@@ -178,7 +179,7 @@ struct wilc {
 
struct semaphore cfg_event;
struct semaphore sync_event;
-   struct semaphore txq_event;
+   struct completion txq_event;
struct completion txq_thread_started;
 
struct task_struct *txq_thread;
diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 11e16d5..1a57135 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -1,3 +1,4 @@
+#include 
 #include "wilc_wlan_if.h"
 #include "wilc_wlan.h"
 #include "wilc_wfi_netdevice.h"
@@ -89,7 +90,7 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
 
spin_unlock_irqrestore(>txq_spinlock, flags);
 
-   up(>txq_event);
+   complete(>txq_event);
 }
 
 static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
@@ -119,7 +120,7 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
 
spin_unlock_irqrestore(>txq_spinlock, flags);
up(>txq_add_to_head_cs);
-   up(>txq_event);
+   complete(>txq_event);
 
return 0;
 }
@@ -287,7 +288,8 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct 
net_device *dev)
spin_unlock_irqrestore(>txq_spinlock, wilc->txq_spinlock_flags);
 
while (dropped > 0) {
-   wilc_lock_timeout(wilc, >txq_event, 1);
+   wait_for_completion_timeout(>txq_event,
+   msecs_to_jiffies(1));
dropped--;
}
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 5/5] staging: wilc1000: Remove semaphore close_exit_sync

2016-06-14 Thread Binoy Jayan
The semaphore 'close_exit_sync' does not serve any purpose other
than delaying the deregistration of the device which it is trying
to protect from shared access. 'up' is called only when a subdevice
is closed and not when it is opened. So, the semaphore count only
goes up when the device is used.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/wilc1000/linux_wlan.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 39fe350..f87a30f 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -31,8 +31,6 @@ static struct notifier_block g_dev_notifier = {
.notifier_call = dev_state_ev_handler
 };
 
-static struct semaphore close_exit_sync;
-
 static int wlan_deinit_locks(struct net_device *dev);
 static void wlan_deinitialize_threads(struct net_device *dev);
 
@@ -1088,7 +1086,6 @@ int wilc_mac_close(struct net_device *ndev)
WILC_WFI_deinit_mon_interface();
}
 
-   up(_exit_sync);
vif->mac_opened = 0;
 
return 0;
@@ -1232,8 +1229,6 @@ void wilc_netdev_cleanup(struct wilc *wilc)
}
 
if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
-   wilc_lock_timeout(wilc, _exit_sync, 5 * 1000);
-
for (i = 0; i < NUM_CONCURRENT_IFC; i++)
if (wilc->vif[i]->ndev)
if (vif[i]->mac_opened)
@@ -1258,8 +1253,6 @@ int wilc_netdev_init(struct wilc **wilc, struct device 
*dev, int io_type,
struct net_device *ndev;
struct wilc *wl;
 
-   sema_init(_exit_sync, 0);
-
wl = kzalloc(sizeof(*wl), GFP_KERNEL);
if (!wl)
return -ENOMEM;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 2/5] staging: wilc1000: Replace semaphore txq_add_to_head_cs with mutex

2016-06-14 Thread Binoy Jayan
The semaphore 'txq_add_to_head_cs' is a simple mutex, so it should be
written as one. Semaphores are going away in the future. Also, removing
the timeout scenario as the error handling code does not propagate the
timeout properly.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/wilc1000/linux_wlan.c |  4 ++--
 drivers/staging/wilc1000/wilc_wfi_netdevice.h |  3 ++-
 drivers/staging/wilc1000/wilc_wlan.c  | 11 ---
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 90f906d..a933551 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -20,7 +20,7 @@
 #include 
 #include 
 #include 
-
+#include 
 #include 
 #include 
 
@@ -679,7 +679,7 @@ static int wlan_init_locks(struct net_device *dev)
mutex_init(>rxq_cs);
 
spin_lock_init(>txq_spinlock);
-   sema_init(>txq_add_to_head_cs, 1);
+   mutex_init(>txq_add_to_head_cs);
 
init_completion(>txq_event);
 
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 12d7c7b..239cd43 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -43,6 +43,7 @@
 #include "wilc_wlan.h"
 #include 
 #include 
+#include 
 
 #define FLOW_CONTROL_LOWER_THRESHOLD   128
 #define FLOW_CONTROL_UPPER_THRESHOLD   256
@@ -171,7 +172,7 @@ struct wilc {
struct wilc_vif *vif[NUM_CONCURRENT_IFC];
u8 open_ifcs;
 
-   struct semaphore txq_add_to_head_cs;
+   struct mutex txq_add_to_head_cs;
spinlock_t txq_spinlock;
 
struct mutex rxq_cs;
diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 1a57135..9afbe8d 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -99,9 +99,7 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
unsigned long flags;
struct wilc *wilc = vif->wilc;
 
-   if (wilc_lock_timeout(wilc, >txq_add_to_head_cs,
-   CFG_PKTS_TIMEOUT))
-   return -1;
+   mutex_lock(>txq_add_to_head_cs);
 
spin_lock_irqsave(>txq_spinlock, flags);
 
@@ -119,7 +117,7 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
wilc->txq_entries += 1;
 
spin_unlock_irqrestore(>txq_spinlock, flags);
-   up(>txq_add_to_head_cs);
+   mutex_unlock(>txq_add_to_head_cs);
complete(>txq_event);
 
return 0;
@@ -573,8 +571,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 
*txq_count)
if (wilc->quit)
break;
 
-   wilc_lock_timeout(wilc, >txq_add_to_head_cs,
-   CFG_PKTS_TIMEOUT);
+   mutex_lock(>txq_add_to_head_cs);
wilc_wlan_txq_filter_dup_tcp_ack(dev);
tqe = wilc_wlan_txq_get_first(wilc);
i = 0;
@@ -755,7 +752,7 @@ _end_:
if (ret != 1)
break;
} while (0);
-   up(>txq_add_to_head_cs);
+   mutex_unlock(>txq_add_to_head_cs);
 
wilc->txq_exit = 1;
*txq_count = wilc->txq_entries;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 3/5] staging: wilc1000: Replace semaphore cfg_event with completion

2016-06-14 Thread Binoy Jayan
The semaphore 'cfg_event' is used as completion, so convert
it to a struct completion type.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/wilc1000/linux_wlan.c |  2 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h |  2 +-
 drivers/staging/wilc1000/wilc_wlan.c  | 15 ---
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index a933551..81a469a 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -683,7 +683,7 @@ static int wlan_init_locks(struct net_device *dev)
 
init_completion(>txq_event);
 
-   sema_init(>cfg_event, 0);
+   init_completion(>cfg_event);
sema_init(>sync_event, 0);
init_completion(>txq_thread_started);
 
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 239cd43..5fbc07c 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -178,7 +178,7 @@ struct wilc {
struct mutex rxq_cs;
struct mutex hif_cs;
 
-   struct semaphore cfg_event;
+   struct completion cfg_event;
struct semaphore sync_event;
struct completion txq_event;
struct completion txq_thread_started;
diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 9afbe8d..19a5809 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -310,7 +310,7 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, 
u8 *buffer,
netdev_dbg(vif->ndev, "Adding config packet ...\n");
if (wilc->quit) {
netdev_dbg(vif->ndev, "Return due to clear function\n");
-   up(>cfg_event);
+   complete(>cfg_event);
return 0;
}
 
@@ -769,7 +769,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc)
 
do {
if (wilc->quit) {
-   up(>cfg_event);
+   complete(>cfg_event);
break;
}
rqe = wilc_wlan_rxq_remove(wilc);
@@ -820,7 +820,7 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc)
wilc_wlan_cfg_indicate_rx(wilc, 
[pkt_offset + offset], pkt_len, );
if (rsp.type == WILC_CFG_RSP) {
if (wilc->cfg_seq_no == 
rsp.seq_no)
-   up(>cfg_event);
+   
complete(>cfg_event);
} else if (rsp.type == 
WILC_CFG_RSP_STATUS) {
wilc_mac_indicate(wilc, 
WILC_MAC_INDICATE_STATUS);
 
@@ -1228,11 +1228,12 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, 
u16 wid, u8 *buffer,
if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
ret_size = 0;
 
-   if (wilc_lock_timeout(wilc, >cfg_event,
-   CFG_PKTS_TIMEOUT)) {
+   if (!wait_for_completion_timeout(>cfg_event,
+   msecs_to_jiffies(CFG_PKTS_TIMEOUT))) {
netdev_dbg(vif->ndev, "Set Timed Out\n");
ret_size = 0;
}
+
wilc->cfg_frame_in_use = 0;
wilc->cfg_frame_offset = 0;
wilc->cfg_seq_no += 1;
@@ -1265,8 +1266,8 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, 
u16 wid, int commit,
if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
ret_size = 0;
 
-   if (wilc_lock_timeout(wilc, >cfg_event,
-   CFG_PKTS_TIMEOUT)) {
+   if (!wait_for_completion_timeout(>cfg_event,
+   msecs_to_jiffies(CFG_PKTS_TIMEOUT))) {
netdev_dbg(vif->ndev, "Get Timed Out\n");
ret_size = 0;
}
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 4/5] staging: wilc1000: Replace semaphore sync_event with completion

2016-06-14 Thread Binoy Jayan
The semaphore 'sync_event' is used as completion, so convert
it to a struct completion type. Also, return -ETIME if the return
value of wait_for_completion_timeout is 0.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/wilc1000/linux_wlan.c | 10 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 81a469a..39fe350 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -241,7 +241,7 @@ void wilc_mac_indicate(struct wilc *wilc, int flag)
  (unsigned char *), 4);
if (wilc->mac_status == WILC_MAC_STATUS_INIT) {
wilc->mac_status = status;
-   up(>sync_event);
+   complete(>sync_event);
} else {
wilc->mac_status = status;
}
@@ -386,9 +386,9 @@ static int linux_wlan_start_firmware(struct net_device *dev)
if (ret < 0)
return ret;
 
-   ret = wilc_lock_timeout(wilc, >sync_event, 5000);
-   if (ret)
-   return ret;
+   if (!wait_for_completion_timeout(>sync_event,
+   msecs_to_jiffies(5000)))
+   return -ETIME;
 
return 0;
 }
@@ -684,7 +684,7 @@ static int wlan_init_locks(struct net_device *dev)
init_completion(>txq_event);
 
init_completion(>cfg_event);
-   sema_init(>sync_event, 0);
+   init_completion(>sync_event);
init_completion(>txq_thread_started);
 
return 0;
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 5fbc07c..5cc6a82 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -179,7 +179,7 @@ struct wilc {
struct mutex hif_cs;
 
struct completion cfg_event;
-   struct semaphore sync_event;
+   struct completion sync_event;
struct completion txq_event;
struct completion txq_thread_started;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 1/5] staging: wilc1000: Replace semaphore txq_event with completion

2016-06-14 Thread Binoy Jayan
The semaphore 'txq_event' is used as completion, so convert it
to a struct completion type.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/wilc1000/linux_wlan.c | 8 
 drivers/staging/wilc1000/wilc_wfi_netdevice.h | 3 ++-
 drivers/staging/wilc1000/wilc_wlan.c  | 8 +---
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 4f93c11..90f906d 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -316,7 +316,7 @@ static int linux_wlan_txq_task(void *vp)
 
complete(>txq_thread_started);
while (1) {
-   down(>txq_event);
+   wait_for_completion(>txq_event);
 
if (wl->close) {
complete(>txq_thread_started);
@@ -650,7 +650,7 @@ void wilc1000_wlan_deinit(struct net_device *dev)
mutex_unlock(>hif_cs);
}
if (>txq_event)
-   up(>txq_event);
+   wait_for_completion(>txq_event);
 
wlan_deinitialize_threads(dev);
deinit_irq(dev);
@@ -681,7 +681,7 @@ static int wlan_init_locks(struct net_device *dev)
spin_lock_init(>txq_spinlock);
sema_init(>txq_add_to_head_cs, 1);
 
-   sema_init(>txq_event, 0);
+   init_completion(>txq_event);
 
sema_init(>cfg_event, 0);
sema_init(>sync_event, 0);
@@ -738,7 +738,7 @@ static void wlan_deinitialize_threads(struct net_device 
*dev)
wl->close = 1;
 
if (>txq_event)
-   up(>txq_event);
+   complete(>txq_event);
 
if (wl->txq_thread) {
kthread_stop(wl->txq_thread);
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 3a561df6..12d7c7b 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -42,6 +42,7 @@
 #include "host_interface.h"
 #include "wilc_wlan.h"
 #include 
+#include 
 
 #define FLOW_CONTROL_LOWER_THRESHOLD   128
 #define FLOW_CONTROL_UPPER_THRESHOLD   256
@@ -178,7 +179,7 @@ struct wilc {
 
struct semaphore cfg_event;
struct semaphore sync_event;
-   struct semaphore txq_event;
+   struct completion txq_event;
struct completion txq_thread_started;
 
struct task_struct *txq_thread;
diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 11e16d5..1a57135 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -1,3 +1,4 @@
+#include 
 #include "wilc_wlan_if.h"
 #include "wilc_wlan.h"
 #include "wilc_wfi_netdevice.h"
@@ -89,7 +90,7 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
 
spin_unlock_irqrestore(>txq_spinlock, flags);
 
-   up(>txq_event);
+   complete(>txq_event);
 }
 
 static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
@@ -119,7 +120,7 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
 
spin_unlock_irqrestore(>txq_spinlock, flags);
up(>txq_add_to_head_cs);
-   up(>txq_event);
+   complete(>txq_event);
 
return 0;
 }
@@ -287,7 +288,8 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct 
net_device *dev)
spin_unlock_irqrestore(>txq_spinlock, wilc->txq_spinlock_flags);
 
while (dropped > 0) {
-   wilc_lock_timeout(wilc, >txq_event, 1);
+   wait_for_completion_timeout(>txq_event,
+   msecs_to_jiffies(1));
dropped--;
}
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 5/5] staging: wilc1000: Remove semaphore close_exit_sync

2016-06-14 Thread Binoy Jayan
The semaphore 'close_exit_sync' does not serve any purpose other
than delaying the deregistration of the device which it is trying
to protect from shared access. 'up' is called only when a subdevice
is closed and not when it is opened. So, the semaphore count only
goes up when the device is used.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
---
 drivers/staging/wilc1000/linux_wlan.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 39fe350..f87a30f 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -31,8 +31,6 @@ static struct notifier_block g_dev_notifier = {
.notifier_call = dev_state_ev_handler
 };
 
-static struct semaphore close_exit_sync;
-
 static int wlan_deinit_locks(struct net_device *dev);
 static void wlan_deinitialize_threads(struct net_device *dev);
 
@@ -1088,7 +1086,6 @@ int wilc_mac_close(struct net_device *ndev)
WILC_WFI_deinit_mon_interface();
}
 
-   up(_exit_sync);
vif->mac_opened = 0;
 
return 0;
@@ -1232,8 +1229,6 @@ void wilc_netdev_cleanup(struct wilc *wilc)
}
 
if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
-   wilc_lock_timeout(wilc, _exit_sync, 5 * 1000);
-
for (i = 0; i < NUM_CONCURRENT_IFC; i++)
if (wilc->vif[i]->ndev)
if (vif[i]->mac_opened)
@@ -1258,8 +1253,6 @@ int wilc_netdev_init(struct wilc **wilc, struct device 
*dev, int io_type,
struct net_device *ndev;
struct wilc *wl;
 
-   sema_init(_exit_sync, 0);
-
wl = kzalloc(sizeof(*wl), GFP_KERNEL);
if (!wl)
return -ENOMEM;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 0/5] *** staging: wilc1000: Replace semaphores with mutexes or completions ***

2016-06-14 Thread Binoy Jayan
These are a set of patches [v3] which removes semaphores from:

drivers/staging/wilc1000

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

Changes w.r.t. review comments on v1

1. Whitespace removed in patch 3
2. Removed semaphore 'close_exit_sync'
3. To rework on patch 6 and send in a seperate patch series

Binoy Jayan (5):
  staging: wilc1000: Replace semaphore txq_event with completion
  staging: wilc1000: Replace semaphore txq_add_to_head_cs with mutex
  staging: wilc1000: Replace semaphore cfg_event with completion
  staging: wilc1000: Replace semaphore sync_event with completion
  staging: wilc1000: Remove semaphore close_exit_sync

 drivers/staging/wilc1000/linux_wlan.c | 31 ++--
 drivers/staging/wilc1000/wilc_wfi_netdevice.h | 10 
 drivers/staging/wilc1000/wilc_wlan.c  | 34 +--
 3 files changed, 35 insertions(+), 40 deletions(-)

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



[PATCH v3 0/5] *** staging: wilc1000: Replace semaphores with mutexes or completions ***

2016-06-14 Thread Binoy Jayan
These are a set of patches [v3] which removes semaphores from:

drivers/staging/wilc1000

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

Changes w.r.t. review comments on v1

1. Whitespace removed in patch 3
2. Removed semaphore 'close_exit_sync'
3. To rework on patch 6 and send in a seperate patch series

Binoy Jayan (5):
  staging: wilc1000: Replace semaphore txq_event with completion
  staging: wilc1000: Replace semaphore txq_add_to_head_cs with mutex
  staging: wilc1000: Replace semaphore cfg_event with completion
  staging: wilc1000: Replace semaphore sync_event with completion
  staging: wilc1000: Remove semaphore close_exit_sync

 drivers/staging/wilc1000/linux_wlan.c | 31 ++--
 drivers/staging/wilc1000/wilc_wfi_netdevice.h | 10 
 drivers/staging/wilc1000/wilc_wlan.c  | 34 +--
 3 files changed, 35 insertions(+), 40 deletions(-)

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



Re: [PATCH] net: hns: update the dependency

2016-06-14 Thread David Miller
From: Yisen Zhuang 
Date: Mon, 13 Jun 2016 19:56:27 +0800

> From: Kejian Yan 
> 
> After the patchset about adding support of ACPI (commit id is 6343488)
> being applied, HNS does not depend on OF. It depends on OF or ACPI, so
> the Kconfig file needs to be updated.
> 
> Signed-off-by: Kejian Yan 
> Signed-off-by: Yisen Zhuang 

Why did you submit this same exact patch 3 times?


Re: [PATCH] net: hns: update the dependency

2016-06-14 Thread David Miller
From: Yisen Zhuang 
Date: Mon, 13 Jun 2016 19:56:27 +0800

> From: Kejian Yan 
> 
> After the patchset about adding support of ACPI (commit id is 6343488)
> being applied, HNS does not depend on OF. It depends on OF or ACPI, so
> the Kconfig file needs to be updated.
> 
> Signed-off-by: Kejian Yan 
> Signed-off-by: Yisen Zhuang 

Why did you submit this same exact patch 3 times?


Re: [PATCH net-next] net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)

2016-06-14 Thread David Miller
From: Netanel Belgazal 
Date: Mon, 13 Jun 2016 11:46:13 +0300

> +#define ena_trc_dbg(format, arg...) \
> + pr_debug("[ENA_COM: %s] " format, __func__, ##arg)
> +#define ena_trc_info(format, arg...) \
> + pr_info("[ENA_COM: %s] " format, __func__, ##arg)
> +#define ena_trc_warn(format, arg...) \
> + pr_warn("[ENA_COM: %s] " format, __func__, ##arg)
> +#define ena_trc_err(format, arg...) \
> + pr_err("[ENA_COM: %s] " format, __func__, ##arg)

These custom tracing macros are quite inappropriate.

We have the function tracer in the kernel when that is needed.  So spitting
out __func__ all over the place is not something that should be found in
drivers these days.

And one can modify pr_fmt do make pr_debug et al. have whatever prefix
one wants.

I suspect there will be several rounds of review to weed out things
like this.  You can preempt a lot of that by removing as much in your
driver that the kernel has existing facilities for.

Thanks.


Re: [PATCH net-next] net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)

2016-06-14 Thread David Miller
From: Netanel Belgazal 
Date: Mon, 13 Jun 2016 11:46:13 +0300

> +#define ena_trc_dbg(format, arg...) \
> + pr_debug("[ENA_COM: %s] " format, __func__, ##arg)
> +#define ena_trc_info(format, arg...) \
> + pr_info("[ENA_COM: %s] " format, __func__, ##arg)
> +#define ena_trc_warn(format, arg...) \
> + pr_warn("[ENA_COM: %s] " format, __func__, ##arg)
> +#define ena_trc_err(format, arg...) \
> + pr_err("[ENA_COM: %s] " format, __func__, ##arg)

These custom tracing macros are quite inappropriate.

We have the function tracer in the kernel when that is needed.  So spitting
out __func__ all over the place is not something that should be found in
drivers these days.

And one can modify pr_fmt do make pr_debug et al. have whatever prefix
one wants.

I suspect there will be several rounds of review to weed out things
like this.  You can preempt a lot of that by removing as much in your
driver that the kernel has existing facilities for.

Thanks.


[PATCH v2 1/5] staging: wilc1000: Replace semaphore txq_event with completion

2016-06-14 Thread Binoy Jayan
The semaphore 'txq_event' is used as completion, so convert it
to a struct completion type.

Signed-off-by: Binoy Jayan 
---
 drivers/staging/wilc1000/linux_wlan.c | 8 
 drivers/staging/wilc1000/wilc_wfi_netdevice.h | 3 ++-
 drivers/staging/wilc1000/wilc_wlan.c  | 8 +---
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 4f93c11..90f906d 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -316,7 +316,7 @@ static int linux_wlan_txq_task(void *vp)
 
complete(>txq_thread_started);
while (1) {
-   down(>txq_event);
+   wait_for_completion(>txq_event);
 
if (wl->close) {
complete(>txq_thread_started);
@@ -650,7 +650,7 @@ void wilc1000_wlan_deinit(struct net_device *dev)
mutex_unlock(>hif_cs);
}
if (>txq_event)
-   up(>txq_event);
+   wait_for_completion(>txq_event);
 
wlan_deinitialize_threads(dev);
deinit_irq(dev);
@@ -681,7 +681,7 @@ static int wlan_init_locks(struct net_device *dev)
spin_lock_init(>txq_spinlock);
sema_init(>txq_add_to_head_cs, 1);
 
-   sema_init(>txq_event, 0);
+   init_completion(>txq_event);
 
sema_init(>cfg_event, 0);
sema_init(>sync_event, 0);
@@ -738,7 +738,7 @@ static void wlan_deinitialize_threads(struct net_device 
*dev)
wl->close = 1;
 
if (>txq_event)
-   up(>txq_event);
+   complete(>txq_event);
 
if (wl->txq_thread) {
kthread_stop(wl->txq_thread);
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 3a561df6..12d7c7b 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -42,6 +42,7 @@
 #include "host_interface.h"
 #include "wilc_wlan.h"
 #include 
+#include 
 
 #define FLOW_CONTROL_LOWER_THRESHOLD   128
 #define FLOW_CONTROL_UPPER_THRESHOLD   256
@@ -178,7 +179,7 @@ struct wilc {
 
struct semaphore cfg_event;
struct semaphore sync_event;
-   struct semaphore txq_event;
+   struct completion txq_event;
struct completion txq_thread_started;
 
struct task_struct *txq_thread;
diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 11e16d5..1a57135 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -1,3 +1,4 @@
+#include 
 #include "wilc_wlan_if.h"
 #include "wilc_wlan.h"
 #include "wilc_wfi_netdevice.h"
@@ -89,7 +90,7 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
 
spin_unlock_irqrestore(>txq_spinlock, flags);
 
-   up(>txq_event);
+   complete(>txq_event);
 }
 
 static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
@@ -119,7 +120,7 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
 
spin_unlock_irqrestore(>txq_spinlock, flags);
up(>txq_add_to_head_cs);
-   up(>txq_event);
+   complete(>txq_event);
 
return 0;
 }
@@ -287,7 +288,8 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct 
net_device *dev)
spin_unlock_irqrestore(>txq_spinlock, wilc->txq_spinlock_flags);
 
while (dropped > 0) {
-   wilc_lock_timeout(wilc, >txq_event, 1);
+   wait_for_completion_timeout(>txq_event,
+   msecs_to_jiffies(1));
dropped--;
}
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 1/5] staging: wilc1000: Replace semaphore txq_event with completion

2016-06-14 Thread Binoy Jayan
The semaphore 'txq_event' is used as completion, so convert it
to a struct completion type.

Signed-off-by: Binoy Jayan 
---
 drivers/staging/wilc1000/linux_wlan.c | 8 
 drivers/staging/wilc1000/wilc_wfi_netdevice.h | 3 ++-
 drivers/staging/wilc1000/wilc_wlan.c  | 8 +---
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 4f93c11..90f906d 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -316,7 +316,7 @@ static int linux_wlan_txq_task(void *vp)
 
complete(>txq_thread_started);
while (1) {
-   down(>txq_event);
+   wait_for_completion(>txq_event);
 
if (wl->close) {
complete(>txq_thread_started);
@@ -650,7 +650,7 @@ void wilc1000_wlan_deinit(struct net_device *dev)
mutex_unlock(>hif_cs);
}
if (>txq_event)
-   up(>txq_event);
+   wait_for_completion(>txq_event);
 
wlan_deinitialize_threads(dev);
deinit_irq(dev);
@@ -681,7 +681,7 @@ static int wlan_init_locks(struct net_device *dev)
spin_lock_init(>txq_spinlock);
sema_init(>txq_add_to_head_cs, 1);
 
-   sema_init(>txq_event, 0);
+   init_completion(>txq_event);
 
sema_init(>cfg_event, 0);
sema_init(>sync_event, 0);
@@ -738,7 +738,7 @@ static void wlan_deinitialize_threads(struct net_device 
*dev)
wl->close = 1;
 
if (>txq_event)
-   up(>txq_event);
+   complete(>txq_event);
 
if (wl->txq_thread) {
kthread_stop(wl->txq_thread);
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 3a561df6..12d7c7b 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -42,6 +42,7 @@
 #include "host_interface.h"
 #include "wilc_wlan.h"
 #include 
+#include 
 
 #define FLOW_CONTROL_LOWER_THRESHOLD   128
 #define FLOW_CONTROL_UPPER_THRESHOLD   256
@@ -178,7 +179,7 @@ struct wilc {
 
struct semaphore cfg_event;
struct semaphore sync_event;
-   struct semaphore txq_event;
+   struct completion txq_event;
struct completion txq_thread_started;
 
struct task_struct *txq_thread;
diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 11e16d5..1a57135 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -1,3 +1,4 @@
+#include 
 #include "wilc_wlan_if.h"
 #include "wilc_wlan.h"
 #include "wilc_wfi_netdevice.h"
@@ -89,7 +90,7 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
 
spin_unlock_irqrestore(>txq_spinlock, flags);
 
-   up(>txq_event);
+   complete(>txq_event);
 }
 
 static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
@@ -119,7 +120,7 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
 
spin_unlock_irqrestore(>txq_spinlock, flags);
up(>txq_add_to_head_cs);
-   up(>txq_event);
+   complete(>txq_event);
 
return 0;
 }
@@ -287,7 +288,8 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct 
net_device *dev)
spin_unlock_irqrestore(>txq_spinlock, wilc->txq_spinlock_flags);
 
while (dropped > 0) {
-   wilc_lock_timeout(wilc, >txq_event, 1);
+   wait_for_completion_timeout(>txq_event,
+   msecs_to_jiffies(1));
dropped--;
}
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 0/5] *** staging: wilc1000: Replace semaphores with mutexes or completions ***

2016-06-14 Thread Binoy Jayan
These are a set of patches [v2] which removes semaphores from:

drivers/staging/wilc1000

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

Changes w.r.t. review comments on v1

1. Whitespace removed in patch 3
2. Removed semaphore 'close_exit_sync'
3. To rework on patch 6 and send in a seperate patch series

Binoy Jayan (5):
  staging: wilc1000: Replace semaphore txq_event with completion
  staging: wilc1000: Replace semaphore txq_add_to_head_cs with mutex
  staging: wilc1000: Replace semaphore cfg_event with completion
  staging: wilc1000: Replace semaphore sync_event with completion
  staging: wilc1000: Remove semaphore close_exit_sync

 drivers/staging/wilc1000/linux_wlan.c | 31 ++--
 drivers/staging/wilc1000/wilc_wfi_netdevice.h | 10 
 drivers/staging/wilc1000/wilc_wlan.c  | 34 +--
 3 files changed, 35 insertions(+), 40 deletions(-)

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



[PATCH v2 0/5] *** staging: wilc1000: Replace semaphores with mutexes or completions ***

2016-06-14 Thread Binoy Jayan
These are a set of patches [v2] which removes semaphores from:

drivers/staging/wilc1000

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

Changes w.r.t. review comments on v1

1. Whitespace removed in patch 3
2. Removed semaphore 'close_exit_sync'
3. To rework on patch 6 and send in a seperate patch series

Binoy Jayan (5):
  staging: wilc1000: Replace semaphore txq_event with completion
  staging: wilc1000: Replace semaphore txq_add_to_head_cs with mutex
  staging: wilc1000: Replace semaphore cfg_event with completion
  staging: wilc1000: Replace semaphore sync_event with completion
  staging: wilc1000: Remove semaphore close_exit_sync

 drivers/staging/wilc1000/linux_wlan.c | 31 ++--
 drivers/staging/wilc1000/wilc_wfi_netdevice.h | 10 
 drivers/staging/wilc1000/wilc_wlan.c  | 34 +--
 3 files changed, 35 insertions(+), 40 deletions(-)

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



linux-next: manual merge of the akpm-current tree with the tip tree

2016-06-14 Thread Stephen Rothwell
Hi Andrew,

Today's linux-next merge of the akpm-current tree got a conflict in:

  ipc/sem.c

between commit:

  33ac279677dc ("locking/barriers: Introduce smp_acquire__after_ctrl_dep()")

from the tip tree and commit:

  a1c58ea067cb ("ipc/sem.c: Fix complex_count vs. simple op race")

from the akpm-current tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc ipc/sem.c
index ae72b3cddc8d,11d9e605a619..
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@@ -260,13 -267,20 +267,10 @@@ static void sem_rcu_free(struct rcu_hea
  }
  
  /*
-  * Wait until all currently ongoing simple ops have completed.
 - * spin_unlock_wait() and !spin_is_locked() are not memory barriers, they
 - * are only control barriers.
 - * The code must pair with spin_unlock(>lock) or
 - * spin_unlock(_perm.lock), thus just the control barrier is insufficient.
 - *
 - * smp_rmb() is sufficient, as writes cannot pass the control barrier.
 - */
 -#define ipc_smp_acquire__after_spin_is_unlocked() smp_rmb()
 -
 -/*
+  * Enter the mode suitable for non-simple operations:
   * Caller must own sem_perm.lock.
-  * New simple ops cannot start, because simple ops first check
-  * that sem_perm.lock is free.
-  * that a) sem_perm.lock is free and b) complex_count is 0.
   */
- static void sem_wait_array(struct sem_array *sma)
+ static void complexmode_enter(struct sem_array *sma)
  {
int i;
struct sem *sem;


linux-next: manual merge of the akpm-current tree with the tip tree

2016-06-14 Thread Stephen Rothwell
Hi Andrew,

Today's linux-next merge of the akpm-current tree got a conflict in:

  ipc/sem.c

between commit:

  33ac279677dc ("locking/barriers: Introduce smp_acquire__after_ctrl_dep()")

from the tip tree and commit:

  a1c58ea067cb ("ipc/sem.c: Fix complex_count vs. simple op race")

from the akpm-current tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc ipc/sem.c
index ae72b3cddc8d,11d9e605a619..
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@@ -260,13 -267,20 +267,10 @@@ static void sem_rcu_free(struct rcu_hea
  }
  
  /*
-  * Wait until all currently ongoing simple ops have completed.
 - * spin_unlock_wait() and !spin_is_locked() are not memory barriers, they
 - * are only control barriers.
 - * The code must pair with spin_unlock(>lock) or
 - * spin_unlock(_perm.lock), thus just the control barrier is insufficient.
 - *
 - * smp_rmb() is sufficient, as writes cannot pass the control barrier.
 - */
 -#define ipc_smp_acquire__after_spin_is_unlocked() smp_rmb()
 -
 -/*
+  * Enter the mode suitable for non-simple operations:
   * Caller must own sem_perm.lock.
-  * New simple ops cannot start, because simple ops first check
-  * that sem_perm.lock is free.
-  * that a) sem_perm.lock is free and b) complex_count is 0.
   */
- static void sem_wait_array(struct sem_array *sma)
+ static void complexmode_enter(struct sem_array *sma)
  {
int i;
struct sem *sem;


Re: [PATCH v2 0/5] ipvs: fix backup sync daemon with IPv6, and minor updates

2016-06-14 Thread Julian Anastasov

Hello,

On Tue, 14 Jun 2016, Quentin Armitage wrote:

> This series of patches arise from discovering that:
> ipvsadm --start-daemon backup --mcast-group IPv6_address ...
> would always fail.
> 
> The first patch resolves the problem. The second and third patches are
> optimizations that were noticed while investigating the original problem.
> The fourth patch adds a lock which appears to have been omitted, and the
> final patch adds the recently added sync daemon multicast parameters to
> the log messages that are written when the sync daemons start.
> 
> v2 fixes a compile error in a debug message identified by kbuild test robot.
> Now compiles with CONFIG_IP_VS_DEBUG enabled. Patch 2/5 is modified to correct
> the problem, and patch 3/5 is modifed to apply with the modified patch 2/5.
> 
> Quentin Armitage (5):
>   ipvs: Enable setting IPv6 multicast address for ipvs sync daemon
> backup
>   ipvs: Stop calling __dev_get_by_name() repeatedly when starting sync
> daemon
>   ipvs: Don't check result < 0 after setting result = 0
>   ipvs: Lock socket before setting SK_CAN_REUSE
>   ipvs: log additional sync daemon parameters
> 
>  net/netfilter/ipvs/ip_vs_sync.c |  104 +++---
>  1 files changed, 52 insertions(+), 52 deletions(-)
> 
> -- 
> 1.7.7.6

Thanks for catching this bug. Following are my
comments for the patches:

Patch 1:

I missed the fact that link-local addresses (ffx2) require
binding to ifindex due to __ipv6_addr_needs_scope_id check,
I tested only with a ff05 address. BTW, ff01 is a node-local
address (loopback), you should not use it for IPVS.

Instead of directly writing into sin6_scope_id we can use
'sock->sk->sk_bound_dev_if = ifindex;' before bind(), it will
work for v4 and v6. Let me know if such solution works.

You have to send this patch as a bugfix, it should
apply to the net tree and later will go to stable trees (4.3+),
i.e. 4.4, 4.5, 4.6 and 4.7, I don't see stable 4.3 in
https://www.kernel.org/. You should mention in commit message
that this patch is a fix to specific commit (check
Documentation/SubmittingPatches):

Fixes: d33288172e72 ("ipvs: add more mcast parameters for the sync daemon")

The other patches will go to the net-next tree in
separate patchset but I see little fuzz if patch 2 is applied
without patch 1, so may be this patchset should wait the first
patch to appear in net-next kernel.

Patch 2: looks OK

Patch 3: looks OK

It was done this way to not exceed the 80-char limit.
May be you can reduce the message for the same reason.

Patch 4: looks OK

Before bind() such operations should be safe without locks.

Patch 5:

No need of <> for the commit IDs.

The indentation of existing pr_info in both cases
should not be changed.

Patches 1, 2, 3 have coding style warnings from checkpatch
that can be fixed, you can check them in this way:

scripts/checkpatch.pl --strict /tmp/file.patch

Regards

--
Julian Anastasov 


Re: [PATCH v2 0/5] ipvs: fix backup sync daemon with IPv6, and minor updates

2016-06-14 Thread Julian Anastasov

Hello,

On Tue, 14 Jun 2016, Quentin Armitage wrote:

> This series of patches arise from discovering that:
> ipvsadm --start-daemon backup --mcast-group IPv6_address ...
> would always fail.
> 
> The first patch resolves the problem. The second and third patches are
> optimizations that were noticed while investigating the original problem.
> The fourth patch adds a lock which appears to have been omitted, and the
> final patch adds the recently added sync daemon multicast parameters to
> the log messages that are written when the sync daemons start.
> 
> v2 fixes a compile error in a debug message identified by kbuild test robot.
> Now compiles with CONFIG_IP_VS_DEBUG enabled. Patch 2/5 is modified to correct
> the problem, and patch 3/5 is modifed to apply with the modified patch 2/5.
> 
> Quentin Armitage (5):
>   ipvs: Enable setting IPv6 multicast address for ipvs sync daemon
> backup
>   ipvs: Stop calling __dev_get_by_name() repeatedly when starting sync
> daemon
>   ipvs: Don't check result < 0 after setting result = 0
>   ipvs: Lock socket before setting SK_CAN_REUSE
>   ipvs: log additional sync daemon parameters
> 
>  net/netfilter/ipvs/ip_vs_sync.c |  104 +++---
>  1 files changed, 52 insertions(+), 52 deletions(-)
> 
> -- 
> 1.7.7.6

Thanks for catching this bug. Following are my
comments for the patches:

Patch 1:

I missed the fact that link-local addresses (ffx2) require
binding to ifindex due to __ipv6_addr_needs_scope_id check,
I tested only with a ff05 address. BTW, ff01 is a node-local
address (loopback), you should not use it for IPVS.

Instead of directly writing into sin6_scope_id we can use
'sock->sk->sk_bound_dev_if = ifindex;' before bind(), it will
work for v4 and v6. Let me know if such solution works.

You have to send this patch as a bugfix, it should
apply to the net tree and later will go to stable trees (4.3+),
i.e. 4.4, 4.5, 4.6 and 4.7, I don't see stable 4.3 in
https://www.kernel.org/. You should mention in commit message
that this patch is a fix to specific commit (check
Documentation/SubmittingPatches):

Fixes: d33288172e72 ("ipvs: add more mcast parameters for the sync daemon")

The other patches will go to the net-next tree in
separate patchset but I see little fuzz if patch 2 is applied
without patch 1, so may be this patchset should wait the first
patch to appear in net-next kernel.

Patch 2: looks OK

Patch 3: looks OK

It was done this way to not exceed the 80-char limit.
May be you can reduce the message for the same reason.

Patch 4: looks OK

Before bind() such operations should be safe without locks.

Patch 5:

No need of <> for the commit IDs.

The indentation of existing pr_info in both cases
should not be changed.

Patches 1, 2, 3 have coding style warnings from checkpatch
that can be fixed, you can check them in this way:

scripts/checkpatch.pl --strict /tmp/file.patch

Regards

--
Julian Anastasov 


Re: [PATCH v6 10/11] cpuidle/powernv: Add support for POWER ISA v3 idle states

2016-06-14 Thread Shreyas B Prabhu


On 06/14/2016 04:59 PM, Benjamin Herrenschmidt wrote:
> On Tue, 2016-06-14 at 16:17 +0530, Shreyas B Prabhu wrote:
> 
>>
>> I ignored adding this check because this is part of initcall and we are
>> unlikely to run out of memory at this state. But I'll add the check in
>> next version.
> 
> Why do you malloc the u64 array and not the string pointer array ?
> Shouldn't you either have both on stack or both allocated ?
> 

Yes. I'll make this consistent.

Thanks,
Shreyas



Re: [PATCH v6 10/11] cpuidle/powernv: Add support for POWER ISA v3 idle states

2016-06-14 Thread Shreyas B Prabhu


On 06/14/2016 04:59 PM, Benjamin Herrenschmidt wrote:
> On Tue, 2016-06-14 at 16:17 +0530, Shreyas B Prabhu wrote:
> 
>>
>> I ignored adding this check because this is part of initcall and we are
>> unlikely to run out of memory at this state. But I'll add the check in
>> next version.
> 
> Why do you malloc the u64 array and not the string pointer array ?
> Shouldn't you either have both on stack or both allocated ?
> 

Yes. I'll make this consistent.

Thanks,
Shreyas



Re: [PATCH v4 0/1] pstore/ram: add Device Tree bindings

2016-06-14 Thread Kees Cook
On Tue, Jun 14, 2016 at 2:59 PM, Rob Herring  wrote:
> On Fri, Jun 10, 2016 at 03:50:58PM -0700, Kees Cook wrote:
>> This is a "v4" of Greg Hackmann's DT bindings for ramoops. This is
>> what I'm going to land in the pstore tree unless there are strong and
>> convincing arguments against it. :)
>>
>> I made a number of changes based people's feedback, and I want to get
>> it unblocked. This patch is already carried by Android, and it doesn't
>> need to be out of tree.
>>
>> To respond to Arnd's comment: I like this as the ramoops node, not the
>> pstore node, since it describes the ramoops backend, not the pstore
>> subsystem, which has different controls, and can only have one backend
>> at a time. So it doesn't make sense to me to have this have a redundant
>> extra pstore node, since the very presence of ramoops implies pstore.
>
> Either I don't follow or you don't get Arnd's comment...
>
> IIRC, his suggestion which I agree with was to remove the memory-region
> phandle and just move all the properties into the reserved memory node
> directly. This simplifies things such that we are just describing
> properties of a chunk of memory rather than a Linux specific node for
> virtual driver.

Ah! Okay, I'm a DT newbie, so I think I misunderstood Arnd. :) If it's
easy, can you create a patch for that against the v4 I sent of Greg's
patch? I'm not sure how to do what you're suggesting. :)

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security


Re: [PATCH v4 0/1] pstore/ram: add Device Tree bindings

2016-06-14 Thread Kees Cook
On Tue, Jun 14, 2016 at 2:59 PM, Rob Herring  wrote:
> On Fri, Jun 10, 2016 at 03:50:58PM -0700, Kees Cook wrote:
>> This is a "v4" of Greg Hackmann's DT bindings for ramoops. This is
>> what I'm going to land in the pstore tree unless there are strong and
>> convincing arguments against it. :)
>>
>> I made a number of changes based people's feedback, and I want to get
>> it unblocked. This patch is already carried by Android, and it doesn't
>> need to be out of tree.
>>
>> To respond to Arnd's comment: I like this as the ramoops node, not the
>> pstore node, since it describes the ramoops backend, not the pstore
>> subsystem, which has different controls, and can only have one backend
>> at a time. So it doesn't make sense to me to have this have a redundant
>> extra pstore node, since the very presence of ramoops implies pstore.
>
> Either I don't follow or you don't get Arnd's comment...
>
> IIRC, his suggestion which I agree with was to remove the memory-region
> phandle and just move all the properties into the reserved memory node
> directly. This simplifies things such that we are just describing
> properties of a chunk of memory rather than a Linux specific node for
> virtual driver.

Ah! Okay, I'm a DT newbie, so I think I misunderstood Arnd. :) If it's
easy, can you create a patch for that against the v4 I sent of Greg's
patch? I'm not sure how to do what you're suggesting. :)

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security


[PATCH 1/1] usb: core: of.c: fix defined but not declare warning

2016-06-14 Thread Peter Chen
The helper usb_of_get_child_node is defined at of.c, but missing its
declare as a global function. Fix it by adding related header file
as well as compile it on conditional of CONFIG_OF.

Cc: Greg Kroah-Hartman 
Cc: Arnd Bergmann 
Cc: Alan Stern 
Cc: linux-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: Ben Dooks 
Cc: linux-ker...@lists.codethink.co.uk

Signed-off-by: Peter Chen 
Reported-by: Ben Dooks 
---
 drivers/usb/core/Makefile | 3 ++-
 drivers/usb/core/of.c | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 9780877..da36b78 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -5,8 +5,9 @@
 usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
 usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
 usbcore-y += devio.o notify.o generic.o quirks.o devices.o
-usbcore-y += port.o of.o
+usbcore-y += port.o
 
+usbcore-$(CONFIG_OF)   += of.o
 usbcore-$(CONFIG_PCI)  += hcd-pci.o
 usbcore-$(CONFIG_ACPI) += usb-acpi.o
 
diff --git a/drivers/usb/core/of.c b/drivers/usb/core/of.c
index 2289700..3de4f88 100644
--- a/drivers/usb/core/of.c
+++ b/drivers/usb/core/of.c
@@ -18,6 +18,7 @@
  */
 
 #include 
+#include 
 
 /**
  * usb_of_get_child_node - Find the device node match port number
-- 
1.9.1



[PATCH 1/1] usb: core: of.c: fix defined but not declare warning

2016-06-14 Thread Peter Chen
The helper usb_of_get_child_node is defined at of.c, but missing its
declare as a global function. Fix it by adding related header file
as well as compile it on conditional of CONFIG_OF.

Cc: Greg Kroah-Hartman 
Cc: Arnd Bergmann 
Cc: Alan Stern 
Cc: linux-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: Ben Dooks 
Cc: linux-ker...@lists.codethink.co.uk

Signed-off-by: Peter Chen 
Reported-by: Ben Dooks 
---
 drivers/usb/core/Makefile | 3 ++-
 drivers/usb/core/of.c | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 9780877..da36b78 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -5,8 +5,9 @@
 usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
 usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
 usbcore-y += devio.o notify.o generic.o quirks.o devices.o
-usbcore-y += port.o of.o
+usbcore-y += port.o
 
+usbcore-$(CONFIG_OF)   += of.o
 usbcore-$(CONFIG_PCI)  += hcd-pci.o
 usbcore-$(CONFIG_ACPI) += usb-acpi.o
 
diff --git a/drivers/usb/core/of.c b/drivers/usb/core/of.c
index 2289700..3de4f88 100644
--- a/drivers/usb/core/of.c
+++ b/drivers/usb/core/of.c
@@ -18,6 +18,7 @@
  */
 
 #include 
+#include 
 
 /**
  * usb_of_get_child_node - Find the device node match port number
-- 
1.9.1



Re: [PATCH v3 2/2] media: et8ek8: Add documentation

2016-06-14 Thread Sakari Ailus
Hi Rob,

On Tue, Jun 14, 2016 at 05:05:17PM -0500, Rob Herring wrote:
> On Sat, Jun 11, 2016 at 06:39:53PM +0300, Ivaylo Dimitrov wrote:
> > Add DT bindings description
> 
> Not exactly the best commit msg.
> 
> > 
> > Signed-off-by: Ivaylo Dimitrov 
> > ---
> >  .../bindings/media/i2c/toshiba,et8ek8.txt  | 50 
> > ++
> >  1 file changed, 50 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt 
> > b/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
> > new file mode 100644
> > index 000..997d268
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
> > @@ -0,0 +1,50 @@
> > +Toshiba et8ek8 5MP sensor
> > +
> > +Toshiba et8ek8 5MP sensor is an image sensor found in Nokia N900 device
> > +
> > +More detailed documentation can be found in
> > +Documentation/devicetree/bindings/media/video-interfaces.txt .
> > +
> > +
> > +Mandatory properties
> > +
> > +
> > +- compatible: "toshiba,et8ek8"
> > +- reg: I2C address (0x3e, or an alternative address)
> > +- vana-supply: Analogue voltage supply (VANA), 2.8 volts
> 
> > +- clocks: External clock to the sensor
> > +- clock-frequency: Frequency of the external clock to the sensor
> 
> These should be mutually-exclusive. If you have a clock, then you can 
> get the frequency at runtime.

Yes, you can. But the intention is to set the frequency: the sensor requires
a particular, pre-determined frequency. Typically this is specific to the
board.

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk


Re: [PATCH v3 2/2] media: et8ek8: Add documentation

2016-06-14 Thread Sakari Ailus
Hi Rob,

On Tue, Jun 14, 2016 at 05:05:17PM -0500, Rob Herring wrote:
> On Sat, Jun 11, 2016 at 06:39:53PM +0300, Ivaylo Dimitrov wrote:
> > Add DT bindings description
> 
> Not exactly the best commit msg.
> 
> > 
> > Signed-off-by: Ivaylo Dimitrov 
> > ---
> >  .../bindings/media/i2c/toshiba,et8ek8.txt  | 50 
> > ++
> >  1 file changed, 50 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt 
> > b/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
> > new file mode 100644
> > index 000..997d268
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
> > @@ -0,0 +1,50 @@
> > +Toshiba et8ek8 5MP sensor
> > +
> > +Toshiba et8ek8 5MP sensor is an image sensor found in Nokia N900 device
> > +
> > +More detailed documentation can be found in
> > +Documentation/devicetree/bindings/media/video-interfaces.txt .
> > +
> > +
> > +Mandatory properties
> > +
> > +
> > +- compatible: "toshiba,et8ek8"
> > +- reg: I2C address (0x3e, or an alternative address)
> > +- vana-supply: Analogue voltage supply (VANA), 2.8 volts
> 
> > +- clocks: External clock to the sensor
> > +- clock-frequency: Frequency of the external clock to the sensor
> 
> These should be mutually-exclusive. If you have a clock, then you can 
> get the frequency at runtime.

Yes, you can. But the intention is to set the frequency: the sensor requires
a particular, pre-determined frequency. Typically this is specific to the
board.

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk


Re: [PATCH 1/2] f2fs: detect host-managed SMR by feature flag

2016-06-14 Thread Damien Le Moal
Jaegeuk,

On 6/15/16 03:45, Jaegeuk Kim wrote:
> If mkfs.f2fs gives a feature flag for host-managed SMR, we can set mode=lfs
> by default.
>
> Signed-off-by: Jaegeuk Kim 
> ---
>  fs/f2fs/f2fs.h  | 21 +
>  fs/f2fs/super.c | 14 --
>  2 files changed, 29 insertions(+), 6 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 32be19e..1a19c02 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -133,6 +133,7 @@ struct f2fs_mount_info {
>  };
>
>  #define F2FS_FEATURE_ENCRYPT 0x0001
> +#define F2FS_FEATURE_HMSMR   0x0002
>
>  #define F2FS_HAS_FEATURE(sb, mask)   \
>   ((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
> @@ -2354,6 +2355,26 @@ static inline int f2fs_sb_has_crypto(struct 
> super_block *sb)
>   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_ENCRYPT);
>  }
>
> +static inline int f2fs_sb_mounted_hmsmr(struct super_block *sb)
> +{
> + return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_HMSMR);
> +}
> +
> +static inline void set_opt_mode(struct f2fs_sb_info *sbi, unsigned int mt)
> +{
> + clear_opt(sbi, ADAPTIVE);
> + clear_opt(sbi, LFS);
> +
> + switch (mt) {
> + case F2FS_MOUNT_ADAPTIVE:
> + set_opt(sbi, ADAPTIVE);
> + break;
> + case F2FS_MOUNT_LFS:
> + set_opt(sbi, LFS);
> + break;
> + }
> +}
> +
>  static inline bool f2fs_may_encrypt(struct inode *inode)
>  {
>  #ifdef CONFIG_F2FS_FS_ENCRYPTION
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index edc736d..71b6066 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -515,12 +515,10 @@ static int parse_options(struct super_block *sb, char 
> *options)
>   return -ENOMEM;
>   if (strlen(name) == 8 &&
>   !strncmp(name, "adaptive", 8)) {
> - set_opt(sbi, ADAPTIVE);
> - clear_opt(sbi, LFS);
> + set_opt_mode(sbi, F2FS_MOUNT_ADAPTIVE);
>   } else if (strlen(name) == 3 &&
>   !strncmp(name, "lfs", 3)) {
> - clear_opt(sbi, ADAPTIVE);
> - set_opt(sbi, LFS);
> + set_opt_mode(sbi, F2FS_MOUNT_LFS);
>   } else {
>   kfree(name);
>   return -EINVAL;
> @@ -980,7 +978,10 @@ static void default_options(struct f2fs_sb_info *sbi)
>   set_opt(sbi, EXTENT_CACHE);
>   sbi->sb->s_flags |= MS_LAZYTIME;
>   set_opt(sbi, FLUSH_MERGE);
> - set_opt(sbi, ADAPTIVE);
> + if (f2fs_sb_mounted_hmsmr(sbi->sb))
> + set_opt_mode(sbi, F2FS_MOUNT_LFS);
> + else
> + set_opt_mode(sbi, F2FS_MOUNT_ADAPTIVE);

Strictly speaking, host-aware drives would not require the LFS mode
as any zone of the disk can be randomly written and so the occasional 
in-place updates of the adaptive mode would be OK. However, randomly 
writing host-aware drives can lead to a lot of background activity on 
the drive side for internal management of the accumulated random writes, 
with a potential performance drop over time (this is highly dependent on 
the drive FW implementation though).

So I think it would be good to also enable the LFS mode by default for 
host-aware devices, unless the user has explicitly specified mount with 
adaptive mode (if the user "knows" that the drive FW handles very 
efficiently random writes).

So how about also introducing a F2FS_FEATURE_HASMR feature flag to 
handle these different cases ?

Also, I think that the DISCARD option must be enabled by default for 
HMSMR disks. Otherwise, zones write pointer will never get reset.
The same applies to HASMR devices mounted with the LFS mode.
(In any case, the discard handling does not look like it will always 
align to the device zone size, which will fail on a zoned disk (discard 
granularity is the zone size). I may be missing something though. Still 
checking.)

Best regards.

-- 
Damien Le Moal, Ph.D.
Sr. Manager, System Software Group, HGST Research,
HGST, a Western Digital company
damien.lem...@hgst.com
(+81) 0466-98-3593 (ext. 513593)
1 kirihara-cho, Fujisawa,
Kanagawa, 252-0888 Japan
www.hgst.com
Western Digital Corporation (and its subsidiaries) E-mail Confidentiality 
Notice & Disclaimer:

This e-mail and any files transmitted with it may contain confidential or 
legally privileged information of WDC and/or its affiliates, and are intended 
solely for the use of the individual or entity to which they are addressed. If 
you are not the intended recipient, any disclosure, copying, distribution or 
any action taken or omitted to be taken in reliance on it, is prohibited. If 
you have received this e-mail in error, please notify the sender immediately 
and delete the e-mail in its entirety from your system.



Re: [PATCH 1/2] f2fs: detect host-managed SMR by feature flag

2016-06-14 Thread Damien Le Moal
Jaegeuk,

On 6/15/16 03:45, Jaegeuk Kim wrote:
> If mkfs.f2fs gives a feature flag for host-managed SMR, we can set mode=lfs
> by default.
>
> Signed-off-by: Jaegeuk Kim 
> ---
>  fs/f2fs/f2fs.h  | 21 +
>  fs/f2fs/super.c | 14 --
>  2 files changed, 29 insertions(+), 6 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 32be19e..1a19c02 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -133,6 +133,7 @@ struct f2fs_mount_info {
>  };
>
>  #define F2FS_FEATURE_ENCRYPT 0x0001
> +#define F2FS_FEATURE_HMSMR   0x0002
>
>  #define F2FS_HAS_FEATURE(sb, mask)   \
>   ((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
> @@ -2354,6 +2355,26 @@ static inline int f2fs_sb_has_crypto(struct 
> super_block *sb)
>   return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_ENCRYPT);
>  }
>
> +static inline int f2fs_sb_mounted_hmsmr(struct super_block *sb)
> +{
> + return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_HMSMR);
> +}
> +
> +static inline void set_opt_mode(struct f2fs_sb_info *sbi, unsigned int mt)
> +{
> + clear_opt(sbi, ADAPTIVE);
> + clear_opt(sbi, LFS);
> +
> + switch (mt) {
> + case F2FS_MOUNT_ADAPTIVE:
> + set_opt(sbi, ADAPTIVE);
> + break;
> + case F2FS_MOUNT_LFS:
> + set_opt(sbi, LFS);
> + break;
> + }
> +}
> +
>  static inline bool f2fs_may_encrypt(struct inode *inode)
>  {
>  #ifdef CONFIG_F2FS_FS_ENCRYPTION
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index edc736d..71b6066 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -515,12 +515,10 @@ static int parse_options(struct super_block *sb, char 
> *options)
>   return -ENOMEM;
>   if (strlen(name) == 8 &&
>   !strncmp(name, "adaptive", 8)) {
> - set_opt(sbi, ADAPTIVE);
> - clear_opt(sbi, LFS);
> + set_opt_mode(sbi, F2FS_MOUNT_ADAPTIVE);
>   } else if (strlen(name) == 3 &&
>   !strncmp(name, "lfs", 3)) {
> - clear_opt(sbi, ADAPTIVE);
> - set_opt(sbi, LFS);
> + set_opt_mode(sbi, F2FS_MOUNT_LFS);
>   } else {
>   kfree(name);
>   return -EINVAL;
> @@ -980,7 +978,10 @@ static void default_options(struct f2fs_sb_info *sbi)
>   set_opt(sbi, EXTENT_CACHE);
>   sbi->sb->s_flags |= MS_LAZYTIME;
>   set_opt(sbi, FLUSH_MERGE);
> - set_opt(sbi, ADAPTIVE);
> + if (f2fs_sb_mounted_hmsmr(sbi->sb))
> + set_opt_mode(sbi, F2FS_MOUNT_LFS);
> + else
> + set_opt_mode(sbi, F2FS_MOUNT_ADAPTIVE);

Strictly speaking, host-aware drives would not require the LFS mode
as any zone of the disk can be randomly written and so the occasional 
in-place updates of the adaptive mode would be OK. However, randomly 
writing host-aware drives can lead to a lot of background activity on 
the drive side for internal management of the accumulated random writes, 
with a potential performance drop over time (this is highly dependent on 
the drive FW implementation though).

So I think it would be good to also enable the LFS mode by default for 
host-aware devices, unless the user has explicitly specified mount with 
adaptive mode (if the user "knows" that the drive FW handles very 
efficiently random writes).

So how about also introducing a F2FS_FEATURE_HASMR feature flag to 
handle these different cases ?

Also, I think that the DISCARD option must be enabled by default for 
HMSMR disks. Otherwise, zones write pointer will never get reset.
The same applies to HASMR devices mounted with the LFS mode.
(In any case, the discard handling does not look like it will always 
align to the device zone size, which will fail on a zoned disk (discard 
granularity is the zone size). I may be missing something though. Still 
checking.)

Best regards.

-- 
Damien Le Moal, Ph.D.
Sr. Manager, System Software Group, HGST Research,
HGST, a Western Digital company
damien.lem...@hgst.com
(+81) 0466-98-3593 (ext. 513593)
1 kirihara-cho, Fujisawa,
Kanagawa, 252-0888 Japan
www.hgst.com
Western Digital Corporation (and its subsidiaries) E-mail Confidentiality 
Notice & Disclaimer:

This e-mail and any files transmitted with it may contain confidential or 
legally privileged information of WDC and/or its affiliates, and are intended 
solely for the use of the individual or entity to which they are addressed. If 
you are not the intended recipient, any disclosure, copying, distribution or 
any action taken or omitted to be taken in reliance on it, is prohibited. If 
you have received this e-mail in error, please notify the sender immediately 
and delete the e-mail in its entirety from your system.



Re: [PATCH] rtc: ds1307: Fix relying on reset value for weekday

2016-06-14 Thread Keerthy



On Tuesday 14 June 2016 08:09 PM, Alexandre Belloni wrote:

On 07/06/2016 at 14:59:05 +0530, Keerthy wrote :

Hi Alexandre,

On Wednesday 01 June 2016 06:06 PM, Keerthy wrote:



On Wednesday 01 June 2016 05:48 PM, Alexandre Belloni wrote:

Hi,

On 01/06/2016 at 16:19:07 +0530, Keerthy wrote :

The reset value of weekday is 0x1. This is wrong since
the reset values of the day/month/year make up to Jan 1 2001.
When computed weekday comes out to be Monday. On a scale
of 1-7(Sunday - Saturday) it should be 0x2. So we should not
be relying on the reset value.



Hum, what are the chances that the reset value is actually the correct
date/time?
Won't that be corrected after the first call to set_time? Until then,
the date is not correct so, do we care anyway?


Yes if an alarm is programmed without set_time.

ex: rtcwake -d /dev/rtc0 -s 5

Even the basic rtctest under tools/testing/selftests/timers/rtctest.c fails
as the wday is wrong and no alarm fires.

Instead of relying on some one to call set_time before programming alarm
its better to fix the wday to reflect the current day right?




Maybe I'm missing something here.


Let me know if you feel this is a valid fix.



Well, this is probably a valid fix and I'll take it as is if I don't
find the time to make something more generic.


Okay Thanks.





Re: [PATCH] rtc: ds1307: Fix relying on reset value for weekday

2016-06-14 Thread Keerthy



On Tuesday 14 June 2016 08:09 PM, Alexandre Belloni wrote:

On 07/06/2016 at 14:59:05 +0530, Keerthy wrote :

Hi Alexandre,

On Wednesday 01 June 2016 06:06 PM, Keerthy wrote:



On Wednesday 01 June 2016 05:48 PM, Alexandre Belloni wrote:

Hi,

On 01/06/2016 at 16:19:07 +0530, Keerthy wrote :

The reset value of weekday is 0x1. This is wrong since
the reset values of the day/month/year make up to Jan 1 2001.
When computed weekday comes out to be Monday. On a scale
of 1-7(Sunday - Saturday) it should be 0x2. So we should not
be relying on the reset value.



Hum, what are the chances that the reset value is actually the correct
date/time?
Won't that be corrected after the first call to set_time? Until then,
the date is not correct so, do we care anyway?


Yes if an alarm is programmed without set_time.

ex: rtcwake -d /dev/rtc0 -s 5

Even the basic rtctest under tools/testing/selftests/timers/rtctest.c fails
as the wday is wrong and no alarm fires.

Instead of relying on some one to call set_time before programming alarm
its better to fix the wday to reflect the current day right?




Maybe I'm missing something here.


Let me know if you feel this is a valid fix.



Well, this is probably a valid fix and I'll take it as is if I don't
find the time to make something more generic.


Okay Thanks.





[PATCH -next] Revert "clocksource/drivers/timer-atmel-st: Add the COMPILE_TEST option"

2016-06-14 Thread Guenter Roeck
This reverts commit 7011a4947ca61cd28a8c025b39c98861687e4fb6.

When trying to build parisc:allmodconfig:

drivers/clocksource/timer-atmel-st.c: In function 'at91rm9200_timer_interrupt':
drivers/clocksource/timer-atmel-st.c:76:3: error:
invalid use of undefined type 'struct clock_event_device'

Cc: Daniel Lezcano 
Signed-off-by: Guenter Roeck 
---
 drivers/clocksource/Kconfig | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 0677e81af030..5a921dc913e5 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -335,11 +335,9 @@ config ATMEL_PIT
def_bool SOC_AT91SAM9 || SOC_SAMA5
 
 config ATMEL_ST
-   bool "Atmel ST timer support" if COMPILE_TEST
+   bool
select CLKSRC_OF
select MFD_SYSCON
-   help
- Support for the Atmel ST timer.
 
 config CLKSRC_METAG_GENERIC
def_bool y if METAG
-- 
2.5.0



[PATCH -next] Revert "clocksource/drivers/timer-atmel-st: Add the COMPILE_TEST option"

2016-06-14 Thread Guenter Roeck
This reverts commit 7011a4947ca61cd28a8c025b39c98861687e4fb6.

When trying to build parisc:allmodconfig:

drivers/clocksource/timer-atmel-st.c: In function 'at91rm9200_timer_interrupt':
drivers/clocksource/timer-atmel-st.c:76:3: error:
invalid use of undefined type 'struct clock_event_device'

Cc: Daniel Lezcano 
Signed-off-by: Guenter Roeck 
---
 drivers/clocksource/Kconfig | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 0677e81af030..5a921dc913e5 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -335,11 +335,9 @@ config ATMEL_PIT
def_bool SOC_AT91SAM9 || SOC_SAMA5
 
 config ATMEL_ST
-   bool "Atmel ST timer support" if COMPILE_TEST
+   bool
select CLKSRC_OF
select MFD_SYSCON
-   help
- Support for the Atmel ST timer.
 
 config CLKSRC_METAG_GENERIC
def_bool y if METAG
-- 
2.5.0



[PATCH -next] nios2: clocksource: Fix build error

2016-06-14 Thread Guenter Roeck
gcc has trouble parsing returen.

Fixes: 3e23d81046936 ("clocksource/drivers/nios2: Convert init function to 
return error")
Cc: Daniel Lezcano 
Signed-off-by: Guenter Roeck 
---
 arch/nios2/kernel/time.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c
index f3686f038996..f337eefdccbd 100644
--- a/arch/nios2/kernel/time.c
+++ b/arch/nios2/kernel/time.c
@@ -303,7 +303,7 @@ static __init int nios2_clocksource_init(struct device_node 
*timer)
/* Calibrate the delay loop directly */
lpj_fine = freq / HZ;
 
-   returen 0;
+   return 0;
 }
 
 /*
-- 
2.5.0



[PATCH -next] nios2: clocksource: Fix build error

2016-06-14 Thread Guenter Roeck
gcc has trouble parsing returen.

Fixes: 3e23d81046936 ("clocksource/drivers/nios2: Convert init function to 
return error")
Cc: Daniel Lezcano 
Signed-off-by: Guenter Roeck 
---
 arch/nios2/kernel/time.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c
index f3686f038996..f337eefdccbd 100644
--- a/arch/nios2/kernel/time.c
+++ b/arch/nios2/kernel/time.c
@@ -303,7 +303,7 @@ static __init int nios2_clocksource_init(struct device_node 
*timer)
/* Calibrate the delay loop directly */
lpj_fine = freq / HZ;
 
-   returen 0;
+   return 0;
 }
 
 /*
-- 
2.5.0



[PATCH] sound: aedsp16: Change structure initialisation to C99 style

2016-06-14 Thread Amitoj Kaur Chawla
Replace the in order struct initialisation style with explicit field
style.

The Coccinelle semantic patch used to make this change is as follows:

@decl@
identifier i1,fld;
type T;
field list[n] fs;
@@

struct i1 {
 fs
 T fld;
 ...};

@@
identifier decl.i1,i2,decl.fld;
expression e;
position bad.p, bad.fix;
@@

struct i1 i2@p = { ...,
+ .fld = e
- e@fix
 ,...};

Signed-off-by: Amitoj Kaur Chawla 
---
 sound/oss/aedsp16.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/sound/oss/aedsp16.c b/sound/oss/aedsp16.c
index 35b5912..bb477d5 100644
--- a/sound/oss/aedsp16.c
+++ b/sound/oss/aedsp16.c
@@ -482,13 +482,13 @@ static struct orVals orDMA[] __initdata = {
 };
 
 static struct aedsp16_info ae_config = {
-   DEF_AEDSP16_IOB,
-   DEF_AEDSP16_IRQ,
-   DEF_AEDSP16_MRQ,
-   DEF_AEDSP16_DMA,
-   -1,
-   -1,
-   INIT_NONE
+   .base_io = DEF_AEDSP16_IOB,
+   .irq = DEF_AEDSP16_IRQ,
+   .mpu_irq = DEF_AEDSP16_MRQ,
+   .dma = DEF_AEDSP16_DMA,
+   .mss_base = -1,
+   .mpu_base = -1,
+   .init = INIT_NONE
 };
 
 /*
-- 
1.9.1



[PATCH] sound: aedsp16: Change structure initialisation to C99 style

2016-06-14 Thread Amitoj Kaur Chawla
Replace the in order struct initialisation style with explicit field
style.

The Coccinelle semantic patch used to make this change is as follows:

@decl@
identifier i1,fld;
type T;
field list[n] fs;
@@

struct i1 {
 fs
 T fld;
 ...};

@@
identifier decl.i1,i2,decl.fld;
expression e;
position bad.p, bad.fix;
@@

struct i1 i2@p = { ...,
+ .fld = e
- e@fix
 ,...};

Signed-off-by: Amitoj Kaur Chawla 
---
 sound/oss/aedsp16.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/sound/oss/aedsp16.c b/sound/oss/aedsp16.c
index 35b5912..bb477d5 100644
--- a/sound/oss/aedsp16.c
+++ b/sound/oss/aedsp16.c
@@ -482,13 +482,13 @@ static struct orVals orDMA[] __initdata = {
 };
 
 static struct aedsp16_info ae_config = {
-   DEF_AEDSP16_IOB,
-   DEF_AEDSP16_IRQ,
-   DEF_AEDSP16_MRQ,
-   DEF_AEDSP16_DMA,
-   -1,
-   -1,
-   INIT_NONE
+   .base_io = DEF_AEDSP16_IOB,
+   .irq = DEF_AEDSP16_IRQ,
+   .mpu_irq = DEF_AEDSP16_MRQ,
+   .dma = DEF_AEDSP16_DMA,
+   .mss_base = -1,
+   .mpu_base = -1,
+   .init = INIT_NONE
 };
 
 /*
-- 
1.9.1



Re: [PATCH] locking/qrwlock: fix write unlock issue in big endian

2016-06-14 Thread xinhui



On 2016年06月14日 18:40, Will Deacon wrote:

On Tue, Jun 14, 2016 at 02:11:48PM +0800, xinhui wrote:


On 2016年06月08日 17:22, Will Deacon wrote:

On Thu, Jun 02, 2016 at 06:09:08PM +0800, Pan Xinhui wrote:

strcut __qrwlock has different layout in big endian machine. we need set
the __qrwlock->wmode to NULL, and the address is not >cnts in big
endian machine.

Do as what read unlock does. we are lucky that the __qrwlock->wmode's
val is _QW_LOCKED.


Doesn't this have wider implications for the qrwlocks, for example:

   while ((cnts & _QW_WMASK) == _QW_LOCKED) { ... }

would actually end up looking at the wrong field of the lock?


I does not clearly understand your idea. :(


That's because I'm talking rubbish :) Sorry, I completely confused myself.
Locking is bad enough on its own, but add big-endian to the mix and I'm
all done.


Shouldn't we just remove the #ifdef __LITTLE_ENDIAN stuff from __qrwlock,
given that all the struct members are u8?


No. that makes codes complex. for example

struct __qrwlock lock;

WRITE_ONCE(lock->wmode, _QW_WAITING);
if (atomic_(>cnts) == _QW_WAITING) {
do_something();
}

IF you remove the  #ifdef __LITTLE_ENDIAN stuff from __qrwlock.
codes above obviously will break. And we already have such code.


I was wondering more along the lines of having one definition of the data
structure, but then defining _QW_* differently depending on endianness
(i.e. add a << 24 when big-endian). That way queued_write_unlock can

make sense. And I review all the code, there is not much code to be changed.
I will work out one patch based on your idea :)


stay like it is (having an arch override to handle the big-endian case
is incredibly ugly).


I admit that. HOWEVER from the view of performance, having an arch override is 
acceptable.

thanks
xinhui

Will





Re: [PATCH] locking/qrwlock: fix write unlock issue in big endian

2016-06-14 Thread xinhui



On 2016年06月14日 18:40, Will Deacon wrote:

On Tue, Jun 14, 2016 at 02:11:48PM +0800, xinhui wrote:


On 2016年06月08日 17:22, Will Deacon wrote:

On Thu, Jun 02, 2016 at 06:09:08PM +0800, Pan Xinhui wrote:

strcut __qrwlock has different layout in big endian machine. we need set
the __qrwlock->wmode to NULL, and the address is not >cnts in big
endian machine.

Do as what read unlock does. we are lucky that the __qrwlock->wmode's
val is _QW_LOCKED.


Doesn't this have wider implications for the qrwlocks, for example:

   while ((cnts & _QW_WMASK) == _QW_LOCKED) { ... }

would actually end up looking at the wrong field of the lock?


I does not clearly understand your idea. :(


That's because I'm talking rubbish :) Sorry, I completely confused myself.
Locking is bad enough on its own, but add big-endian to the mix and I'm
all done.


Shouldn't we just remove the #ifdef __LITTLE_ENDIAN stuff from __qrwlock,
given that all the struct members are u8?


No. that makes codes complex. for example

struct __qrwlock lock;

WRITE_ONCE(lock->wmode, _QW_WAITING);
if (atomic_(>cnts) == _QW_WAITING) {
do_something();
}

IF you remove the  #ifdef __LITTLE_ENDIAN stuff from __qrwlock.
codes above obviously will break. And we already have such code.


I was wondering more along the lines of having one definition of the data
structure, but then defining _QW_* differently depending on endianness
(i.e. add a << 24 when big-endian). That way queued_write_unlock can

make sense. And I review all the code, there is not much code to be changed.
I will work out one patch based on your idea :)


stay like it is (having an arch override to handle the big-endian case
is incredibly ugly).


I admit that. HOWEVER from the view of performance, having an arch override is 
acceptable.

thanks
xinhui

Will





[PATCH perf/core v11 09/23] perf probe: Show all cached probes

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

perf probe --list shows all cached probes when --cache
is given. Each caches are shown with on which binary that
probed. e.g.
  -
  # perf probe --cache vfs_read \$params
  # perf probe --cache -x /lib64/libc-2.17.so getaddrinfo \$params
  # perf probe --cache --list
  [kernel.kallsyms] (1466a0a250b5d0070c6d0f03c5fed30b237970a1):
  vfs_read $params
  /usr/lib64/libc-2.17.so (c31ffe7942bfd77b2fca8f9bd5709d387a86d3bc):
  getaddrinfo $params
  -
Note that $params requires debuginfo.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
  Changes in v11:
   - Make build_id_cache__list_all() returns strlist directly. (no error code)
   - Harden build_id_cache__list_all() to check directory entries.
  Changes in v7:
- Remove the top '/' from binary name if it is not a regular file.
---
 tools/perf/Documentation/perf-probe.txt |8 ++
 tools/perf/builtin-probe.c  |2 -
 tools/perf/util/build-id.c  |  108 ++-
 tools/perf/util/build-id.h  |3 +
 tools/perf/util/probe-event.c   |3 +
 tools/perf/util/probe-file.c|   66 ++-
 tools/perf/util/probe-file.h|1 
 7 files changed, 184 insertions(+), 7 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index 947db6f..5a70d45 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -67,7 +67,10 @@ OPTIONS
 
 -l::
 --list[=[GROUP:]EVENT]::
-   List up current probe events. This can also accept filtering patterns 
of event names.
+   List up current probe events. This can also accept filtering patterns of
+   event names.
+   When this is used with --cache, perf shows all cached probes instead of
+   the live probes.
 
 -L::
 --line=::
@@ -110,8 +113,9 @@ OPTIONS
adding and removal operations.
 
 --cache::
-   Cache the probes (with --add option). Any events which successfully 
added
+   (With --add) Cache the probes. Any events which successfully added
are also stored in the cache file.
+   (With --list) Show cached probes.
 
 --max-probes=NUM::
Set the maximum number of probe points for an event. Default is 128.
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 6d7ab431..53e380c0e 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -44,7 +44,7 @@
 
 #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"
 #define DEFAULT_FUNC_FILTER "!_*"
-#define DEFAULT_LIST_FILTER "*:*"
+#define DEFAULT_LIST_FILTER "*"
 
 /* Session management structure */
 static struct {
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 62b1473..0d6093c 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -165,8 +165,7 @@ retry:
return NULL;
 }
 
-static char *build_id_cache__linkname(const char *sbuild_id, char *bf,
- size_t size)
+char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size)
 {
char *tmp = bf;
int ret = asnprintf(, size, "%s/.build-id/%.2s/%s", buildid_dir,
@@ -176,6 +175,36 @@ static char *build_id_cache__linkname(const char 
*sbuild_id, char *bf,
return bf;
 }
 
+char *build_id_cache__origname(const char *sbuild_id)
+{
+   char *linkname;
+   char buf[PATH_MAX];
+   char *ret = NULL, *p;
+   size_t offs = 5;/* == strlen("../..") */
+
+   linkname = build_id_cache__linkname(sbuild_id, NULL, 0);
+   if (!linkname)
+   return NULL;
+
+   if (readlink(linkname, buf, PATH_MAX) < 0)
+   goto out;
+   /* The link should be "../../" */
+   p = strrchr(buf, '/');  /* Cut off the "/" */
+   if (p && (p > buf + offs)) {
+   *p = '\0';
+   if (buf[offs + 1] == '[')
+   offs++; /*
+* This is a DSO name, like [kernel.kallsyms].
+* Skip the first '/', since this is not the
+* cache of a regular file.
+*/
+   ret = strdup(buf + offs);   /* Skip "../..[/]" */
+   }
+out:
+   free(linkname);
+   return ret;
+}
+
 static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
 {
return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
@@ -387,6 +416,81 @@ void disable_buildid_cache(void)
no_buildid_cache = true;
 }
 
+static bool lsdir_bid_head_filter(const char *name __maybe_unused,
+ struct dirent *d __maybe_unused)
+{
+   return (strlen(d->d_name) == 2) &&
+   isxdigit(d->d_name[0]) && isxdigit(d->d_name[1]);
+}
+
+static bool lsdir_bid_tail_filter(const 

[PATCH perf/core v11 09/23] perf probe: Show all cached probes

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

perf probe --list shows all cached probes when --cache
is given. Each caches are shown with on which binary that
probed. e.g.
  -
  # perf probe --cache vfs_read \$params
  # perf probe --cache -x /lib64/libc-2.17.so getaddrinfo \$params
  # perf probe --cache --list
  [kernel.kallsyms] (1466a0a250b5d0070c6d0f03c5fed30b237970a1):
  vfs_read $params
  /usr/lib64/libc-2.17.so (c31ffe7942bfd77b2fca8f9bd5709d387a86d3bc):
  getaddrinfo $params
  -
Note that $params requires debuginfo.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
  Changes in v11:
   - Make build_id_cache__list_all() returns strlist directly. (no error code)
   - Harden build_id_cache__list_all() to check directory entries.
  Changes in v7:
- Remove the top '/' from binary name if it is not a regular file.
---
 tools/perf/Documentation/perf-probe.txt |8 ++
 tools/perf/builtin-probe.c  |2 -
 tools/perf/util/build-id.c  |  108 ++-
 tools/perf/util/build-id.h  |3 +
 tools/perf/util/probe-event.c   |3 +
 tools/perf/util/probe-file.c|   66 ++-
 tools/perf/util/probe-file.h|1 
 7 files changed, 184 insertions(+), 7 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index 947db6f..5a70d45 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -67,7 +67,10 @@ OPTIONS
 
 -l::
 --list[=[GROUP:]EVENT]::
-   List up current probe events. This can also accept filtering patterns 
of event names.
+   List up current probe events. This can also accept filtering patterns of
+   event names.
+   When this is used with --cache, perf shows all cached probes instead of
+   the live probes.
 
 -L::
 --line=::
@@ -110,8 +113,9 @@ OPTIONS
adding and removal operations.
 
 --cache::
-   Cache the probes (with --add option). Any events which successfully 
added
+   (With --add) Cache the probes. Any events which successfully added
are also stored in the cache file.
+   (With --list) Show cached probes.
 
 --max-probes=NUM::
Set the maximum number of probe points for an event. Default is 128.
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 6d7ab431..53e380c0e 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -44,7 +44,7 @@
 
 #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"
 #define DEFAULT_FUNC_FILTER "!_*"
-#define DEFAULT_LIST_FILTER "*:*"
+#define DEFAULT_LIST_FILTER "*"
 
 /* Session management structure */
 static struct {
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 62b1473..0d6093c 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -165,8 +165,7 @@ retry:
return NULL;
 }
 
-static char *build_id_cache__linkname(const char *sbuild_id, char *bf,
- size_t size)
+char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size)
 {
char *tmp = bf;
int ret = asnprintf(, size, "%s/.build-id/%.2s/%s", buildid_dir,
@@ -176,6 +175,36 @@ static char *build_id_cache__linkname(const char 
*sbuild_id, char *bf,
return bf;
 }
 
+char *build_id_cache__origname(const char *sbuild_id)
+{
+   char *linkname;
+   char buf[PATH_MAX];
+   char *ret = NULL, *p;
+   size_t offs = 5;/* == strlen("../..") */
+
+   linkname = build_id_cache__linkname(sbuild_id, NULL, 0);
+   if (!linkname)
+   return NULL;
+
+   if (readlink(linkname, buf, PATH_MAX) < 0)
+   goto out;
+   /* The link should be "../../" */
+   p = strrchr(buf, '/');  /* Cut off the "/" */
+   if (p && (p > buf + offs)) {
+   *p = '\0';
+   if (buf[offs + 1] == '[')
+   offs++; /*
+* This is a DSO name, like [kernel.kallsyms].
+* Skip the first '/', since this is not the
+* cache of a regular file.
+*/
+   ret = strdup(buf + offs);   /* Skip "../..[/]" */
+   }
+out:
+   free(linkname);
+   return ret;
+}
+
 static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
 {
return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
@@ -387,6 +416,81 @@ void disable_buildid_cache(void)
no_buildid_cache = true;
 }
 
+static bool lsdir_bid_head_filter(const char *name __maybe_unused,
+ struct dirent *d __maybe_unused)
+{
+   return (strlen(d->d_name) == 2) &&
+   isxdigit(d->d_name[0]) && isxdigit(d->d_name[1]);
+}
+
+static bool lsdir_bid_tail_filter(const char *name __maybe_unused,
+ struct dirent *d 

[PATCH perf/core v11 21/23] perf probe: Support a special SDT probe format

2016-06-14 Thread Masami Hiramatsu
Support a special SDT probe format which can omit the '%' prefix
only if the SDT group name starts with "sdt_". So, for example
both of "%sdt_libc:setjump" and "sdt_libc:setjump" are acceptable
for perf probe --add.

Suggested-by: Brendan Gregg 
Signed-off-by: Masami Hiramatsu 
---
 tools/perf/Documentation/perf-probe.txt |4 +++-
 tools/perf/util/probe-event.c   |   12 ++--
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index 39e3870..736da44 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -152,7 +152,9 @@ Probe points are defined by following syntax.
  [[GROUP:]EVENT=]SRC;PTN [ARG ...]
 
 4) Pre-defined SDT events or cached event with name
- %[PROVIDER:]SDTEVENT
+ %[sdt_PROVIDER:]SDTEVENT
+ or,
+ sdt_PROVIDER:SDTEVENT
 
 'EVENT' specifies the name of new event, if omitted, it will be set the name 
of the probed function. You can also specify a group name by 'GROUP', if 
omitted, set 'probe' is used for kprobe and 'probe_' is used for uprobe.
 Note that using existing group name can conflict with other events. 
Especially, using the group name reserved for kernel modules can hide embedded 
events in the
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index fa3cbb3..f525d67 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1245,9 +1245,17 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
if (!arg)
return -EINVAL;
 
-   if (arg[0] == '%') {
+   /*
+* If the probe point starts with '%',
+* or starts with "sdt_" and has a ':' but no '=',
+* then it should be a SDT/cached probe point.
+*/
+   if (arg[0] == '%' ||
+   (!strncmp(arg, "sdt_", 4) &&
+!!strchr(arg, ':') && !strchr(arg, '='))) {
pev->sdt = true;
-   arg++;
+   if (arg[0] == '%')
+   arg++;
}
 
ptr = strpbrk(arg, ";=@+%");



[PATCH perf/core v11 19/23] perf probe: Search SDT/cached event from all probe caches

2016-06-14 Thread Masami Hiramatsu
Search SDT/cached event from all probe caches if user doesn't
pass any binary. With this, we don't have to specify target
binary for SDT and named cached events (which start with %).

E.g. without this, a target binary must be passed with -x.

 # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*

With this change, we don't need it anymore.

 # perf probe -a %sdt_libc:\*

Signed-off-by: Masami Hiramatsu 
---
 Changes from v10:
  - Splitted from "perf probe: Allow wildcard for cached events"
---
 tools/perf/util/probe-event.c |  105 ++---
 1 file changed, 86 insertions(+), 19 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 7b41633..81e22f1 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2557,41 +2557,60 @@ static int probe_trace_event__set_name(struct 
probe_trace_event *tev,
return 0;
 }
 
-static int __add_probe_trace_events(struct perf_probe_event *pev,
-struct probe_trace_event *tevs,
-int ntevs, bool allow_suffix)
+static int __open_probe_file_and_namelist(bool uprobe,
+ struct strlist **namelist)
 {
-   int i, fd, ret;
-   struct probe_trace_event *tev = NULL;
-   struct probe_cache *cache = NULL;
-   struct strlist *namelist;
+   int fd;
 
-   fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0));
+   fd = probe_file__open(PF_FL_RW | (uprobe ? PF_FL_UPROBE : 0));
if (fd < 0)
return fd;
 
/* Get current event names */
-   namelist = probe_file__get_namelist(fd);
-   if (!namelist) {
+   *namelist = probe_file__get_namelist(fd);
+   if (!(*namelist)) {
pr_debug("Failed to get current event list.\n");
-   ret = -ENOMEM;
-   goto close_out;
+   close(fd);
+   return -ENOMEM;
}
+   return fd;
+}
+
+static int __add_probe_trace_events(struct perf_probe_event *pev,
+struct probe_trace_event *tevs,
+int ntevs, bool allow_suffix)
+{
+   int i, fd[2] = {-1, -1}, up, ret;
+   struct probe_trace_event *tev = NULL;
+   struct probe_cache *cache = NULL;
+   struct strlist *namelist[2] = {NULL, NULL};
+
+   up = pev->uprobes ? 1 : 0;
+   fd[up] = __open_probe_file_and_namelist(up, [up]);
+   if (fd[up] < 0)
+   return fd[up];
 
ret = 0;
for (i = 0; i < ntevs; i++) {
tev = [i];
+   up = tev->uprobes ? 1 : 0;
+   if (fd[up] == -1) { /* Open the kprobe/uprobe_events */
+   fd[up] = __open_probe_file_and_namelist(up,
+   [up]);
+   if (fd[up] < 0)
+   goto close_out;
+   }
/* Skip if the symbol is out of .text or blacklisted */
if (!tev->point.symbol && !pev->uprobes)
continue;
 
/* Set new name for tev (and update namelist) */
-   ret = probe_trace_event__set_name(tev, pev, namelist,
+   ret = probe_trace_event__set_name(tev, pev, namelist[up],
  allow_suffix);
if (ret < 0)
break;
 
-   ret = probe_file__add_event(fd, tev);
+   ret = probe_file__add_event(fd[up], tev);
if (ret < 0)
break;
 
@@ -2614,9 +2633,12 @@ static int __add_probe_trace_events(struct 
perf_probe_event *pev,
probe_cache__delete(cache);
}
 
-   strlist__delete(namelist);
 close_out:
-   close(fd);
+   for (up = 0; up < 2; up++) {
+   strlist__delete(namelist[up]);
+   if (fd[up] >= 0)
+   close(fd[up]);
+   }
return ret;
 }
 
@@ -2989,6 +3011,48 @@ static int find_cached_events(struct perf_probe_event 
*pev,
return ret;
 }
 
+/* Try to find probe_trace_event from all probe caches */
+static int find_cached_events_all(struct perf_probe_event *pev,
+  struct probe_trace_event **tevs)
+{
+   struct probe_trace_event *tmp_tevs = NULL;
+   struct strlist *bidlist;
+   struct str_node *nd;
+   char *pathname;
+   int ntevs = 0;
+   int ret;
+
+   /* Get the buildid list of all valid caches */
+   bidlist = build_id_cache__list_all(true);
+   if (!bidlist) {
+   ret = -errno;
+   pr_debug("Failed to get buildids: %d\n", ret);
+   return ret;
+   }
+
+   ret = 0;
+   strlist__for_each(nd, bidlist) {
+   pathname = build_id_cache__origname(nd->s);
+   

[PATCH perf/core v11 18/23] perf probe: Allow wildcard for cached events

2016-06-14 Thread Masami Hiramatsu
Allo glob wildcard for reusing cached/SDT events. E.g.

  # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*

This example adds probes for all SDT in libc.
Note that the SDTs must have been scanned by perf buildid-cache.

Signed-off-by: Masami Hiramatsu 
---
 Changes in v10:
  - Split off bugfix, adding interface, and target search patches.
  - Do not export clear_probe_trace_events().
 Changes in v7:
  - Continue to search caches if a build-id cache has no probe cache.
  - Make probe_cache__open() to accept DSO__NAME_KALLSYMS for kernel.
  - Fix to add probes correctly when a wildcard matchs both of
uprobes and kprobes.
 Changes in v5.1:
  - Fix a SEGV bug when a group name is omitted. (Thanks Hemant!)
---
 tools/perf/util/probe-event.c |  107 +++--
 tools/perf/util/probe-file.c  |   38 ---
 tools/perf/util/probe-file.h  |3 +
 3 files changed, 138 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 4aa2cf7..7b41633 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1206,7 +1206,7 @@ static int parse_perf_probe_event_name(char **arg, struct 
perf_probe_event *pev)
ptr = strchr(*arg, ':');
if (ptr) {
*ptr = '\0';
-   if (!is_c_func_name(*arg))
+   if (!pev->sdt && !is_c_func_name(*arg))
goto ng_name;
pev->group = strdup(*arg);
if (!pev->group)
@@ -1214,7 +1214,7 @@ static int parse_perf_probe_event_name(char **arg, struct 
perf_probe_event *pev)
*arg = ptr + 1;
} else
pev->group = NULL;
-   if (!is_c_func_name(*arg)) {
+   if (!pev->sdt && !is_c_func_name(*arg)) {
 ng_name:
semantic_error("%s is bad for event name -it must "
   "follow C symbol-naming rule.\n", *arg);
@@ -1644,6 +1644,7 @@ int parse_probe_trace_command(const char *cmd, struct 
probe_trace_event *tev)
ret = -ENOMEM;
goto out;
}
+   tev->uprobes = (tp->module[0] == '/');
p++;
} else
p = argv[1];
@@ -2518,7 +2519,7 @@ static int probe_trace_event__set_name(struct 
probe_trace_event *tev,
int ret;
 
/* If probe_event or trace_event already have the name, reuse it */
-   if (pev->event)
+   if (pev->event && !pev->sdt)
event = pev->event;
else if (tev->event)
event = tev->event;
@@ -2531,7 +2532,7 @@ static int probe_trace_event__set_name(struct 
probe_trace_event *tev,
else
event = tev->point.realname;
}
-   if (pev->group)
+   if (pev->group && !pev->sdt)
group = pev->group;
else if (tev->group)
group = tev->group;
@@ -2894,6 +2895,100 @@ errout:
 
 bool __weak arch__prefers_symtab(void) { return false; }
 
+/* Concatinate two arrays */
+static void *memcat(void *a, size_t sz_a, void *b, size_t sz_b)
+{
+   void *ret;
+
+   ret = malloc(sz_a + sz_b);
+   if (ret) {
+   memcpy(ret, a, sz_a);
+   memcpy(ret + sz_a, b, sz_b);
+   }
+   return ret;
+}
+
+static int
+concat_probe_trace_events(struct probe_trace_event **tevs, int *ntevs,
+ struct probe_trace_event **tevs2, int ntevs2)
+{
+   struct probe_trace_event *new_tevs;
+   int ret = 0;
+
+   if (ntevs == 0) {
+   *tevs = *tevs2;
+   *ntevs = ntevs2;
+   *tevs2 = NULL;
+   return 0;
+   }
+
+   if (*ntevs + ntevs2 > probe_conf.max_probes)
+   ret = -E2BIG;
+   else {
+   /* Concatinate the array of probe_trace_event */
+   new_tevs = memcat(*tevs, (*ntevs) * sizeof(**tevs),
+ *tevs2, ntevs2 * sizeof(**tevs2));
+   if (!new_tevs)
+   ret = -ENOMEM;
+   else {
+   free(*tevs);
+   *tevs = new_tevs;
+   *ntevs += ntevs2;
+   }
+   }
+   if (ret < 0)
+   clear_probe_trace_events(*tevs2, ntevs2);
+   zfree(tevs2);
+
+   return ret;
+}
+
+/*
+ * Try to find probe_trace_event from given probe caches. Return the number
+ * of cached events found, if an error occurs return the error.
+ */
+static int find_cached_events(struct perf_probe_event *pev,
+ struct probe_trace_event **tevs,
+ const char *target)
+{
+   struct probe_cache *cache;
+   struct probe_cache_entry *entry;
+   struct probe_trace_event *tmp_tevs = NULL;
+   int ntevs = 0;
+   int ret = 0;
+
+   cache = probe_cache__new(target);
+   /* Return 0 ("not found") if the 

[PATCH perf/core v11 23/23] perf-test: Add a test case for SDT event

2016-06-14 Thread Masami Hiramatsu
Add a basic test case for SDT event support.
This test scans an SDT event in perftools and
check whether the SDT event is correctly stored
into the buildid cache.

Signed-off-by: Masami Hiramatsu 
---
 tools/perf/tests/Build  |1 
 tools/perf/tests/builtin-test.c |4 +
 tools/perf/tests/sdt.c  |  115 +++
 tools/perf/tests/tests.h|1 
 4 files changed, 121 insertions(+)
 create mode 100644 tools/perf/tests/sdt.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 66a2898..4158422 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -39,6 +39,7 @@ perf-y += stat.o
 perf-y += event_update.o
 perf-y += event-times.o
 perf-y += backward-ring-buffer.o
+perf-y += sdt.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 0e95c20..c0e0ccb 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -212,6 +212,10 @@ static struct test generic_tests[] = {
.func = test__backward_ring_buffer,
},
{
+   .desc = "Test SDT event probing",
+   .func = test__sdt_event,
+   },
+   {
.func = NULL,
},
 };
diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c
new file mode 100644
index 000..f59d210
--- /dev/null
+++ b/tools/perf/tests/sdt.c
@@ -0,0 +1,115 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "tests.h"
+#include "debug.h"
+#include "probe-file.h"
+#include "build-id.h"
+
+/* To test SDT event, we need libelf support to scan elf binary */
+#if defined(HAVE_SDT_EVENT) && defined(HAVE_LIBELF_SUPPORT)
+
+#include 
+
+static int target_function(void)
+{
+   DTRACE_PROBE(perf, test_target);
+   return TEST_OK;
+}
+
+/* Copied from builtin-buildid-cache.c */
+static int build_id_cache__add_file(const char *filename)
+{
+   char sbuild_id[SBUILD_ID_SIZE];
+   u8 build_id[BUILD_ID_SIZE];
+   int err;
+
+   err = filename__read_build_id(filename, _id, sizeof(build_id));
+   if (err < 0) {
+   pr_debug("Failed to read build id of %s\n", filename);
+   return err;
+   }
+
+   build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
+   err = build_id_cache__add_s(sbuild_id, filename, false, false);
+   if (err < 0)
+   pr_debug("Failed to add build id cache of %s\n", filename);
+   return err;
+}
+
+static char *get_self_path(void)
+{
+   char *buf = calloc(PATH_MAX, sizeof(char));
+
+   if (buf && readlink("/proc/self/exe", buf, PATH_MAX) < 0) {
+   pr_debug("Failed to get correct path of perf\n");
+   free(buf);
+   return NULL;
+   }
+   return buf;
+}
+
+static int search_cached_probe(const char *target,
+  const char *group, const char *event)
+{
+   struct probe_cache *cache = probe_cache__new(target);
+   int ret = 0;
+
+   if (!cache) {
+   pr_debug("Failed to open probe cache of %s\n", target);
+   return -EINVAL;
+   }
+
+   if (!probe_cache__find_by_name(cache, group, event)) {
+   pr_debug("Failed to find %s:%s in the cache\n", group, event);
+   ret = -ENOENT;
+   }
+   probe_cache__delete(cache);
+
+   return ret;
+}
+
+int test__sdt_event(int subtests __maybe_unused)
+{
+   int ret = TEST_FAIL;
+   char __tempdir[] = "./test-buildid-XX";
+   char *tempdir = NULL, *myself = get_self_path();
+
+   if (myself == NULL || mkdtemp(__tempdir) == NULL) {
+   pr_debug("Failed to make a tempdir for build-id cache\n");
+   goto error;
+   }
+   /* Note that buildid_dir must be an absolute path */
+   tempdir = realpath(__tempdir, NULL);
+
+   /* At first, scan itself */
+   set_buildid_dir(tempdir);
+   if (build_id_cache__add_file(myself) < 0)
+   goto error_rmdir;
+
+   /* Open a cache and make sure the SDT is stored */
+   if (search_cached_probe(myself, "sdt_perf", "test_target") < 0)
+   goto error_rmdir;
+
+   /* TBD: probing on the SDT event and collect logs */
+
+   /* Call the target and get an event */
+   ret = target_function();
+
+error_rmdir:
+   /* Cleanup temporary buildid dir */
+   rm_rf(tempdir);
+error:
+   free(tempdir);
+   free(myself);
+   return ret;
+}
+#else
+int test__sdt_event(int subtests __maybe_unused)
+{
+   pr_debug("Skip SDT event test because SDT support is not compiled\n");
+   return TEST_SKIP;
+}
+#endif
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index c57e72c..93cfb0b 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -87,6 +87,7 @@ int test__synthesize_stat_round(int 

[PATCH perf/core v11 21/23] perf probe: Support a special SDT probe format

2016-06-14 Thread Masami Hiramatsu
Support a special SDT probe format which can omit the '%' prefix
only if the SDT group name starts with "sdt_". So, for example
both of "%sdt_libc:setjump" and "sdt_libc:setjump" are acceptable
for perf probe --add.

Suggested-by: Brendan Gregg 
Signed-off-by: Masami Hiramatsu 
---
 tools/perf/Documentation/perf-probe.txt |4 +++-
 tools/perf/util/probe-event.c   |   12 ++--
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index 39e3870..736da44 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -152,7 +152,9 @@ Probe points are defined by following syntax.
  [[GROUP:]EVENT=]SRC;PTN [ARG ...]
 
 4) Pre-defined SDT events or cached event with name
- %[PROVIDER:]SDTEVENT
+ %[sdt_PROVIDER:]SDTEVENT
+ or,
+ sdt_PROVIDER:SDTEVENT
 
 'EVENT' specifies the name of new event, if omitted, it will be set the name 
of the probed function. You can also specify a group name by 'GROUP', if 
omitted, set 'probe' is used for kprobe and 'probe_' is used for uprobe.
 Note that using existing group name can conflict with other events. 
Especially, using the group name reserved for kernel modules can hide embedded 
events in the
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index fa3cbb3..f525d67 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1245,9 +1245,17 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
if (!arg)
return -EINVAL;
 
-   if (arg[0] == '%') {
+   /*
+* If the probe point starts with '%',
+* or starts with "sdt_" and has a ':' but no '=',
+* then it should be a SDT/cached probe point.
+*/
+   if (arg[0] == '%' ||
+   (!strncmp(arg, "sdt_", 4) &&
+!!strchr(arg, ':') && !strchr(arg, '='))) {
pev->sdt = true;
-   arg++;
+   if (arg[0] == '%')
+   arg++;
}
 
ptr = strpbrk(arg, ";=@+%");



[PATCH perf/core v11 19/23] perf probe: Search SDT/cached event from all probe caches

2016-06-14 Thread Masami Hiramatsu
Search SDT/cached event from all probe caches if user doesn't
pass any binary. With this, we don't have to specify target
binary for SDT and named cached events (which start with %).

E.g. without this, a target binary must be passed with -x.

 # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*

With this change, we don't need it anymore.

 # perf probe -a %sdt_libc:\*

Signed-off-by: Masami Hiramatsu 
---
 Changes from v10:
  - Splitted from "perf probe: Allow wildcard for cached events"
---
 tools/perf/util/probe-event.c |  105 ++---
 1 file changed, 86 insertions(+), 19 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 7b41633..81e22f1 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2557,41 +2557,60 @@ static int probe_trace_event__set_name(struct 
probe_trace_event *tev,
return 0;
 }
 
-static int __add_probe_trace_events(struct perf_probe_event *pev,
-struct probe_trace_event *tevs,
-int ntevs, bool allow_suffix)
+static int __open_probe_file_and_namelist(bool uprobe,
+ struct strlist **namelist)
 {
-   int i, fd, ret;
-   struct probe_trace_event *tev = NULL;
-   struct probe_cache *cache = NULL;
-   struct strlist *namelist;
+   int fd;
 
-   fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0));
+   fd = probe_file__open(PF_FL_RW | (uprobe ? PF_FL_UPROBE : 0));
if (fd < 0)
return fd;
 
/* Get current event names */
-   namelist = probe_file__get_namelist(fd);
-   if (!namelist) {
+   *namelist = probe_file__get_namelist(fd);
+   if (!(*namelist)) {
pr_debug("Failed to get current event list.\n");
-   ret = -ENOMEM;
-   goto close_out;
+   close(fd);
+   return -ENOMEM;
}
+   return fd;
+}
+
+static int __add_probe_trace_events(struct perf_probe_event *pev,
+struct probe_trace_event *tevs,
+int ntevs, bool allow_suffix)
+{
+   int i, fd[2] = {-1, -1}, up, ret;
+   struct probe_trace_event *tev = NULL;
+   struct probe_cache *cache = NULL;
+   struct strlist *namelist[2] = {NULL, NULL};
+
+   up = pev->uprobes ? 1 : 0;
+   fd[up] = __open_probe_file_and_namelist(up, [up]);
+   if (fd[up] < 0)
+   return fd[up];
 
ret = 0;
for (i = 0; i < ntevs; i++) {
tev = [i];
+   up = tev->uprobes ? 1 : 0;
+   if (fd[up] == -1) { /* Open the kprobe/uprobe_events */
+   fd[up] = __open_probe_file_and_namelist(up,
+   [up]);
+   if (fd[up] < 0)
+   goto close_out;
+   }
/* Skip if the symbol is out of .text or blacklisted */
if (!tev->point.symbol && !pev->uprobes)
continue;
 
/* Set new name for tev (and update namelist) */
-   ret = probe_trace_event__set_name(tev, pev, namelist,
+   ret = probe_trace_event__set_name(tev, pev, namelist[up],
  allow_suffix);
if (ret < 0)
break;
 
-   ret = probe_file__add_event(fd, tev);
+   ret = probe_file__add_event(fd[up], tev);
if (ret < 0)
break;
 
@@ -2614,9 +2633,12 @@ static int __add_probe_trace_events(struct 
perf_probe_event *pev,
probe_cache__delete(cache);
}
 
-   strlist__delete(namelist);
 close_out:
-   close(fd);
+   for (up = 0; up < 2; up++) {
+   strlist__delete(namelist[up]);
+   if (fd[up] >= 0)
+   close(fd[up]);
+   }
return ret;
 }
 
@@ -2989,6 +3011,48 @@ static int find_cached_events(struct perf_probe_event 
*pev,
return ret;
 }
 
+/* Try to find probe_trace_event from all probe caches */
+static int find_cached_events_all(struct perf_probe_event *pev,
+  struct probe_trace_event **tevs)
+{
+   struct probe_trace_event *tmp_tevs = NULL;
+   struct strlist *bidlist;
+   struct str_node *nd;
+   char *pathname;
+   int ntevs = 0;
+   int ret;
+
+   /* Get the buildid list of all valid caches */
+   bidlist = build_id_cache__list_all(true);
+   if (!bidlist) {
+   ret = -errno;
+   pr_debug("Failed to get buildids: %d\n", ret);
+   return ret;
+   }
+
+   ret = 0;
+   strlist__for_each(nd, bidlist) {
+   pathname = build_id_cache__origname(nd->s);
+   ret = 

[PATCH perf/core v11 18/23] perf probe: Allow wildcard for cached events

2016-06-14 Thread Masami Hiramatsu
Allo glob wildcard for reusing cached/SDT events. E.g.

  # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*

This example adds probes for all SDT in libc.
Note that the SDTs must have been scanned by perf buildid-cache.

Signed-off-by: Masami Hiramatsu 
---
 Changes in v10:
  - Split off bugfix, adding interface, and target search patches.
  - Do not export clear_probe_trace_events().
 Changes in v7:
  - Continue to search caches if a build-id cache has no probe cache.
  - Make probe_cache__open() to accept DSO__NAME_KALLSYMS for kernel.
  - Fix to add probes correctly when a wildcard matchs both of
uprobes and kprobes.
 Changes in v5.1:
  - Fix a SEGV bug when a group name is omitted. (Thanks Hemant!)
---
 tools/perf/util/probe-event.c |  107 +++--
 tools/perf/util/probe-file.c  |   38 ---
 tools/perf/util/probe-file.h  |3 +
 3 files changed, 138 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 4aa2cf7..7b41633 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1206,7 +1206,7 @@ static int parse_perf_probe_event_name(char **arg, struct 
perf_probe_event *pev)
ptr = strchr(*arg, ':');
if (ptr) {
*ptr = '\0';
-   if (!is_c_func_name(*arg))
+   if (!pev->sdt && !is_c_func_name(*arg))
goto ng_name;
pev->group = strdup(*arg);
if (!pev->group)
@@ -1214,7 +1214,7 @@ static int parse_perf_probe_event_name(char **arg, struct 
perf_probe_event *pev)
*arg = ptr + 1;
} else
pev->group = NULL;
-   if (!is_c_func_name(*arg)) {
+   if (!pev->sdt && !is_c_func_name(*arg)) {
 ng_name:
semantic_error("%s is bad for event name -it must "
   "follow C symbol-naming rule.\n", *arg);
@@ -1644,6 +1644,7 @@ int parse_probe_trace_command(const char *cmd, struct 
probe_trace_event *tev)
ret = -ENOMEM;
goto out;
}
+   tev->uprobes = (tp->module[0] == '/');
p++;
} else
p = argv[1];
@@ -2518,7 +2519,7 @@ static int probe_trace_event__set_name(struct 
probe_trace_event *tev,
int ret;
 
/* If probe_event or trace_event already have the name, reuse it */
-   if (pev->event)
+   if (pev->event && !pev->sdt)
event = pev->event;
else if (tev->event)
event = tev->event;
@@ -2531,7 +2532,7 @@ static int probe_trace_event__set_name(struct 
probe_trace_event *tev,
else
event = tev->point.realname;
}
-   if (pev->group)
+   if (pev->group && !pev->sdt)
group = pev->group;
else if (tev->group)
group = tev->group;
@@ -2894,6 +2895,100 @@ errout:
 
 bool __weak arch__prefers_symtab(void) { return false; }
 
+/* Concatinate two arrays */
+static void *memcat(void *a, size_t sz_a, void *b, size_t sz_b)
+{
+   void *ret;
+
+   ret = malloc(sz_a + sz_b);
+   if (ret) {
+   memcpy(ret, a, sz_a);
+   memcpy(ret + sz_a, b, sz_b);
+   }
+   return ret;
+}
+
+static int
+concat_probe_trace_events(struct probe_trace_event **tevs, int *ntevs,
+ struct probe_trace_event **tevs2, int ntevs2)
+{
+   struct probe_trace_event *new_tevs;
+   int ret = 0;
+
+   if (ntevs == 0) {
+   *tevs = *tevs2;
+   *ntevs = ntevs2;
+   *tevs2 = NULL;
+   return 0;
+   }
+
+   if (*ntevs + ntevs2 > probe_conf.max_probes)
+   ret = -E2BIG;
+   else {
+   /* Concatinate the array of probe_trace_event */
+   new_tevs = memcat(*tevs, (*ntevs) * sizeof(**tevs),
+ *tevs2, ntevs2 * sizeof(**tevs2));
+   if (!new_tevs)
+   ret = -ENOMEM;
+   else {
+   free(*tevs);
+   *tevs = new_tevs;
+   *ntevs += ntevs2;
+   }
+   }
+   if (ret < 0)
+   clear_probe_trace_events(*tevs2, ntevs2);
+   zfree(tevs2);
+
+   return ret;
+}
+
+/*
+ * Try to find probe_trace_event from given probe caches. Return the number
+ * of cached events found, if an error occurs return the error.
+ */
+static int find_cached_events(struct perf_probe_event *pev,
+ struct probe_trace_event **tevs,
+ const char *target)
+{
+   struct probe_cache *cache;
+   struct probe_cache_entry *entry;
+   struct probe_trace_event *tmp_tevs = NULL;
+   int ntevs = 0;
+   int ret = 0;
+
+   cache = probe_cache__new(target);
+   /* Return 0 ("not found") if the target has no probe 

[PATCH perf/core v11 23/23] perf-test: Add a test case for SDT event

2016-06-14 Thread Masami Hiramatsu
Add a basic test case for SDT event support.
This test scans an SDT event in perftools and
check whether the SDT event is correctly stored
into the buildid cache.

Signed-off-by: Masami Hiramatsu 
---
 tools/perf/tests/Build  |1 
 tools/perf/tests/builtin-test.c |4 +
 tools/perf/tests/sdt.c  |  115 +++
 tools/perf/tests/tests.h|1 
 4 files changed, 121 insertions(+)
 create mode 100644 tools/perf/tests/sdt.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 66a2898..4158422 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -39,6 +39,7 @@ perf-y += stat.o
 perf-y += event_update.o
 perf-y += event-times.o
 perf-y += backward-ring-buffer.o
+perf-y += sdt.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 0e95c20..c0e0ccb 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -212,6 +212,10 @@ static struct test generic_tests[] = {
.func = test__backward_ring_buffer,
},
{
+   .desc = "Test SDT event probing",
+   .func = test__sdt_event,
+   },
+   {
.func = NULL,
},
 };
diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c
new file mode 100644
index 000..f59d210
--- /dev/null
+++ b/tools/perf/tests/sdt.c
@@ -0,0 +1,115 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "tests.h"
+#include "debug.h"
+#include "probe-file.h"
+#include "build-id.h"
+
+/* To test SDT event, we need libelf support to scan elf binary */
+#if defined(HAVE_SDT_EVENT) && defined(HAVE_LIBELF_SUPPORT)
+
+#include 
+
+static int target_function(void)
+{
+   DTRACE_PROBE(perf, test_target);
+   return TEST_OK;
+}
+
+/* Copied from builtin-buildid-cache.c */
+static int build_id_cache__add_file(const char *filename)
+{
+   char sbuild_id[SBUILD_ID_SIZE];
+   u8 build_id[BUILD_ID_SIZE];
+   int err;
+
+   err = filename__read_build_id(filename, _id, sizeof(build_id));
+   if (err < 0) {
+   pr_debug("Failed to read build id of %s\n", filename);
+   return err;
+   }
+
+   build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
+   err = build_id_cache__add_s(sbuild_id, filename, false, false);
+   if (err < 0)
+   pr_debug("Failed to add build id cache of %s\n", filename);
+   return err;
+}
+
+static char *get_self_path(void)
+{
+   char *buf = calloc(PATH_MAX, sizeof(char));
+
+   if (buf && readlink("/proc/self/exe", buf, PATH_MAX) < 0) {
+   pr_debug("Failed to get correct path of perf\n");
+   free(buf);
+   return NULL;
+   }
+   return buf;
+}
+
+static int search_cached_probe(const char *target,
+  const char *group, const char *event)
+{
+   struct probe_cache *cache = probe_cache__new(target);
+   int ret = 0;
+
+   if (!cache) {
+   pr_debug("Failed to open probe cache of %s\n", target);
+   return -EINVAL;
+   }
+
+   if (!probe_cache__find_by_name(cache, group, event)) {
+   pr_debug("Failed to find %s:%s in the cache\n", group, event);
+   ret = -ENOENT;
+   }
+   probe_cache__delete(cache);
+
+   return ret;
+}
+
+int test__sdt_event(int subtests __maybe_unused)
+{
+   int ret = TEST_FAIL;
+   char __tempdir[] = "./test-buildid-XX";
+   char *tempdir = NULL, *myself = get_self_path();
+
+   if (myself == NULL || mkdtemp(__tempdir) == NULL) {
+   pr_debug("Failed to make a tempdir for build-id cache\n");
+   goto error;
+   }
+   /* Note that buildid_dir must be an absolute path */
+   tempdir = realpath(__tempdir, NULL);
+
+   /* At first, scan itself */
+   set_buildid_dir(tempdir);
+   if (build_id_cache__add_file(myself) < 0)
+   goto error_rmdir;
+
+   /* Open a cache and make sure the SDT is stored */
+   if (search_cached_probe(myself, "sdt_perf", "test_target") < 0)
+   goto error_rmdir;
+
+   /* TBD: probing on the SDT event and collect logs */
+
+   /* Call the target and get an event */
+   ret = target_function();
+
+error_rmdir:
+   /* Cleanup temporary buildid dir */
+   rm_rf(tempdir);
+error:
+   free(tempdir);
+   free(myself);
+   return ret;
+}
+#else
+int test__sdt_event(int subtests __maybe_unused)
+{
+   pr_debug("Skip SDT event test because SDT support is not compiled\n");
+   return TEST_SKIP;
+}
+#endif
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index c57e72c..93cfb0b 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -87,6 +87,7 @@ int test__synthesize_stat_round(int subtest);
 int 

[PATCH perf/core v11 17/23] perf: probe-cache: Add for_each_probe_cache_entry() wrapper

2016-06-14 Thread Masami Hiramatsu
Add for_each_probe_cache_entry() wrapper macro
for hiding list in probe_cache.

Signed-off-by: Masami Hiramatsu 
---
 Changes in v10:
  - Splitted from "perf probe: Allow wildcard for cached events"
---
 tools/perf/util/probe-file.c |8 
 tools/perf/util/probe-file.h |2 ++
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index a6a2d60..503d7c2 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -546,7 +546,7 @@ probe_cache__find(struct probe_cache *pcache, struct 
perf_probe_event *pev)
if (!cmd)
return NULL;
 
-   list_for_each_entry(entry, >entries, node) {
+   for_each_probe_cache_entry(entry, pcache) {
if (pev->sdt) {
if (entry->pev.event &&
streql(entry->pev.event, pev->event) &&
@@ -576,7 +576,7 @@ probe_cache__find_by_name(struct probe_cache *pcache,
 {
struct probe_cache_entry *entry = NULL;
 
-   list_for_each_entry(entry, >entries, node) {
+   for_each_probe_cache_entry(entry, pcache) {
/* Hit if same event name or same command-string */
if (streql(entry->pev.group, group) &&
streql(entry->pev.event, event))
@@ -746,7 +746,7 @@ int probe_cache__commit(struct probe_cache *pcache)
if (ret < 0)
goto out;
 
-   list_for_each_entry(entry, >entries, node) {
+   for_each_probe_cache_entry(entry, pcache) {
ret = probe_cache_entry__write(entry, pcache->fd);
pr_debug("Cache committed: %d\n", ret);
if (ret < 0)
@@ -788,7 +788,7 @@ static int probe_cache__show_entries(struct probe_cache 
*pcache,
 {
struct probe_cache_entry *entry;
 
-   list_for_each_entry(entry, >entries, node) {
+   for_each_probe_cache_entry(entry, pcache) {
if (probe_cache_entry__compare(entry, filter))
printf("%s\n", entry->spev);
}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index b2b4c39..837f530 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -21,6 +21,8 @@ struct probe_cache {
 
 #define PF_FL_UPROBE   1
 #define PF_FL_RW   2
+#define for_each_probe_cache_entry(entry, pcache) \
+   list_for_each_entry(entry, >entries, node)
 
 /* probe-file.c depends on libelf */
 #ifdef HAVE_LIBELF_SUPPORT



[PATCH perf/core v11 22/23] perf build: Add sdt feature detection

2016-06-14 Thread Masami Hiramatsu
Will be used to define SDT events in perf test code.

Signed-off-by: Masami Hiramatsu 
---
 tools/build/Makefile.feature   |3 ++-
 tools/build/feature/Makefile   |6 +-
 tools/build/feature/test-all.c |5 +
 tools/build/feature/test-sdt.c |7 +++
 tools/perf/Makefile.perf   |3 +++
 tools/perf/config/Makefile |   10 ++
 tools/perf/tests/make  |3 ++-
 7 files changed, 34 insertions(+), 3 deletions(-)
 create mode 100644 tools/build/feature/test-sdt.c

diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 57c8f98..6bc7767 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -60,7 +60,8 @@ FEATURE_TESTS_BASIC :=\
zlib\
lzma\
get_cpuid   \
-   bpf
+   bpf \
+   sdt
 
 # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
 # of all feature tests
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 3d88f09..82d357f 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -43,7 +43,8 @@ FILES=\
test-zlib.bin   \
test-lzma.bin   \
test-bpf.bin\
-   test-get_cpuid.bin
+   test-get_cpuid.bin  \
+   test-sdt.bin
 
 FILES := $(addprefix $(OUTPUT),$(FILES))
 
@@ -205,6 +206,9 @@ $(OUTPUT)test-get_cpuid.bin:
 $(OUTPUT)test-bpf.bin:
$(BUILD)
 
+$(OUTPUT)test-sdt.bin:
+   $(BUILD)
+
 -include $(OUTPUT)*.d
 
 ###
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index a282e8c..f538c5f 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -137,6 +137,10 @@
 # include "test-libcrypto.c"
 #undef main
 
+#define main main_test_sdt
+# include "test-sdt.c"
+#undef main
+
 int main(int argc, char *argv[])
 {
main_test_libpython();
@@ -168,6 +172,7 @@ int main(int argc, char *argv[])
main_test_get_cpuid();
main_test_bpf();
main_test_libcrypto();
+   main_test_sdt();
 
return 0;
 }
diff --git a/tools/build/feature/test-sdt.c b/tools/build/feature/test-sdt.c
new file mode 100644
index 000..e4531a6
--- /dev/null
+++ b/tools/build/feature/test-sdt.c
@@ -0,0 +1,7 @@
+#include 
+
+int main(void)
+{
+   DTRACE_PROBE(provider, name);
+   return 0;
+}
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index bde8cba..a818388 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -81,6 +81,9 @@ include ../scripts/utilities.mak
 #
 # Define NO_LIBBPF if you do not want BPF support
 #
+# Define NO_SDT if you do not want to define SDT event in perf tools,
+# note that it doesn't disable SDT scanning support.
+#
 # Define FEATURES_DUMP to provide features detection dump file
 # and bypass the feature detection
 
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 098874b..f6c91a6 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -345,6 +345,16 @@ ifndef NO_LIBELF
   endif # NO_LIBBPF
 endif # NO_LIBELF
 
+ifndef NO_SDT
+  ifneq ($(feature-sdt), 1)
+msg := $(warning No sys/sdt.h found, no SDT events are defined, please 
install systemtap-sdt-devel or systemtap-sdt-dev);
+NO_SDT := 1;
+  else
+CFLAGS += -DHAVE_SDT_EVENT
+$(call detected,CONFIG_SDT_EVENT)
+  endif
+endif
+
 ifdef PERF_HAVE_JITDUMP
   ifndef NO_DWARF
 $(call detected,CONFIG_JITDUMP)
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index cac15d9..ac801be 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -81,6 +81,7 @@ make_no_libbionic   := NO_LIBBIONIC=1
 make_no_auxtrace:= NO_AUXTRACE=1
 make_no_libbpf := NO_LIBBPF=1
 make_no_libcrypto   := NO_LIBCRYPTO=1
+make_no_sdt:= NO_SDT=1
 make_tags   := tags
 make_cscope := cscope
 make_help   := help
@@ -104,7 +105,7 @@ make_minimal:= NO_LIBPERL=1 NO_LIBPYTHON=1 
NO_NEWT=1 NO_GTK2=1
 make_minimal+= NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
 make_minimal+= NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
 make_minimal+= NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
-make_minimal+= NO_LIBCRYPTO=1
+make_minimal+= NO_LIBCRYPTO=1 NO_SDT=1
 
 # $(run) contains all available tests
 run := make_pure



[PATCH perf/core v11 16/23] perf-list: Skip SDTs placed in invalid binaries

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

Skip SDTs placed in invalid (non-exist, or older version)
binaries. Note that perf-probe --cache --list and
perf-probe --cache --del still handle all the caches
including invalid binaries.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v7:
  - Validate build-id via sysfs if it is for kallsyms,
 Changes in v4:
  - Rename a parameter 'valid' to 'validonly' :)
---
 tools/perf/builtin-probe.c |2 +-
 tools/perf/util/build-id.c |   33 -
 tools/perf/util/build-id.h |2 +-
 tools/perf/util/parse-events.c |2 +-
 tools/perf/util/probe-file.c   |2 +-
 5 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 6c2c0d1..03ea72d 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)
struct str_node *nd;
int ret;
 
-   bidlist = build_id_cache__list_all();
+   bidlist = build_id_cache__list_all(false);
if (!bidlist) {
ret = -errno;
pr_debug("Failed to get buildids: %d\n", ret);
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 95d4490..a28ef39 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -206,6 +206,31 @@ out:
return ret;
 }
 
+/* Check if the given build_id cache is valid on current running system */
+static bool build_id_cache__valid_id(char *sbuild_id)
+{
+   char real_sbuild_id[SBUILD_ID_SIZE] = "";
+   char *pathname;
+   int ret = 0;
+   bool result = false;
+
+   pathname = build_id_cache__origname(sbuild_id);
+   if (!pathname)
+   return false;
+
+   if (!strcmp(pathname, DSO__NAME_KALLSYMS))
+   ret = sysfs__sprintf_build_id("/", real_sbuild_id);
+   else if (pathname[0] == '/')
+   ret = filename__sprintf_build_id(pathname, real_sbuild_id);
+   else
+   ret = -EINVAL;  /* Should we support other special DSO cache? */
+   if (ret >= 0)
+   result = (strcmp(sbuild_id, real_sbuild_id) == 0);
+   free(pathname);
+
+   return result;
+}
+
 static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
 {
return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
@@ -433,13 +458,17 @@ static bool lsdir_bid_tail_filter(const char *name 
__maybe_unused,
return (i == SBUILD_ID_SIZE - 3) && (d->d_name[i] == '\0');
 }
 
-struct strlist *build_id_cache__list_all(void)
+struct strlist *build_id_cache__list_all(bool validonly)
 {
struct strlist *toplist, *linklist = NULL, *bidlist;
struct str_node *nd, *nd2;
char *topdir, *linkdir = NULL;
char sbuild_id[SBUILD_ID_SIZE];
 
+   /* for filename__ functions */
+   if (validonly)
+   symbol__init(NULL);
+
/* Open the top-level directory */
if (asprintf(, "%s/.build-id/", buildid_dir) < 0)
return NULL;
@@ -470,6 +499,8 @@ struct strlist *build_id_cache__list_all(void)
if (snprintf(sbuild_id, SBUILD_ID_SIZE, "%s%s",
 nd->s, nd2->s) != SBUILD_ID_SIZE - 1)
goto err_out;
+   if (validonly && !build_id_cache__valid_id(sbuild_id))
+   continue;
if (strlist__add(bidlist, sbuild_id) < 0)
goto err_out;
}
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index b742e27..64e740f 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -34,7 +34,7 @@ char *build_id_cache__origname(const char *sbuild_id);
 char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
   bool is_kallsyms, bool is_vdso);
-struct strlist *build_id_cache__list_all(void);
+struct strlist *build_id_cache__list_all(bool validonly);
 int build_id_cache__list_build_ids(const char *pathname,
   struct strlist **result);
 bool build_id_cache__cached(const char *sbuild_id);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 05bd505..54a4e2b 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -2002,7 +2002,7 @@ void print_sdt_events(const char *subsys_glob, const char 
*event_glob,
pr_debug("Failed to allocate new strlist for SDT\n");
return;
}
-   bidlist = build_id_cache__list_all();
+   bidlist = build_id_cache__list_all(true);
if (!bidlist) {
pr_debug("Failed to get buildids: %d\n", 

[PATCH perf/core v11 20/23] perf probe: Support @BUILDID or @FILE suffix for SDT events

2016-06-14 Thread Masami Hiramatsu
Support @BUILDID or @FILE suffix for SDT events. This allows
perf to add probes on SDTs/pre-cached events on given FILE
or the file which has given BUILDID (also, this complements
BUILDID.)
For example, both gcc and libstdc++ has same SDTs as below.
If you would like to add a probe on sdt_libstdcxx:catch on gcc,
you can do as below.

  
  # perf list sdt | tail -n 6
sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27)   [SDT event]
sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
  # perf probe -a %sdt_libstdcxx:catch@0cc
  Added new event:
sdt_libstdcxx:catch  (on %catch in /usr/bin/gcc)

  You can now use it in all perf tools, such as:

perf record -e sdt_libstdcxx:catch -aR sleep 1
  

Signed-off-by: Masami Hiramatsu 
---
 tools/perf/util/build-id.c|   43 +
 tools/perf/util/build-id.h|1 +
 tools/perf/util/probe-event.c |   17 ++--
 3 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index a28ef39..7b78a33 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -523,6 +523,49 @@ err_out:
goto out_free;
 }
 
+static bool str_is_build_id(const char *maybe_sbuild_id, size_t len)
+{
+   size_t i;
+
+   for (i = 0; i < len; i++) {
+   if (!isxdigit(maybe_sbuild_id[i]))
+   return false;
+   }
+   return true;
+}
+
+/* Return the valid complete build-id */
+char *build_id_cache__complement(const char *incomplete_sbuild_id)
+{
+   struct strlist *bidlist;
+   struct str_node *nd, *cand = NULL;
+   char *sbuild_id = NULL;
+   size_t len = strlen(incomplete_sbuild_id);
+
+   if (len >= SBUILD_ID_SIZE ||
+   !str_is_build_id(incomplete_sbuild_id, len))
+   return NULL;
+
+   bidlist = build_id_cache__list_all(true);
+   if (!bidlist)
+   return NULL;
+
+   strlist__for_each(nd, bidlist) {
+   if (strncmp(nd->s, incomplete_sbuild_id, len) != 0)
+   continue;
+   if (cand) { /* Error: There are more than 2 candidates. */
+   cand = NULL;
+   break;
+   }
+   cand = nd;
+   }
+   if (cand)
+   sbuild_id = strdup(cand->s);
+   strlist__delete(bidlist);
+
+   return sbuild_id;
+}
+
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
   bool is_kallsyms, bool is_vdso)
 {
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 64e740f..d279906 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char 
*bf, size_t size);
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
   bool is_kallsyms, bool is_vdso);
 struct strlist *build_id_cache__list_all(bool validonly);
+char *build_id_cache__complement(const char *incomplete_sbuild_id);
 int build_id_cache__list_build_ids(const char *pathname,
   struct strlist **result);
 bool build_id_cache__cached(const char *sbuild_id);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 81e22f1..fa3cbb3 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1253,8 +1253,21 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
ptr = strpbrk(arg, ";=@+%");
if (pev->sdt) {
if (ptr) {
-   semantic_error("%s must contain only an SDT event 
name.\n", arg);
-   return -EINVAL;
+   if (*ptr != '@') {
+   semantic_error("%s must be an SDT name.\n",
+  arg);
+   return -EINVAL;
+   }
+   /* This must be a target file name or build id */
+   tmp = build_id_cache__complement(ptr + 1);
+   if (tmp) {
+   pev->target = build_id_cache__origname(tmp);
+   free(tmp);
+   } else
+   pev->target = strdup(ptr + 1);
+   if (!pev->target)
+   return -ENOMEM;
+   *ptr = '\0';
}
ret = parse_perf_probe_event_name(, pev);
if (ret == 0) {



[PATCH perf/core v11 17/23] perf: probe-cache: Add for_each_probe_cache_entry() wrapper

2016-06-14 Thread Masami Hiramatsu
Add for_each_probe_cache_entry() wrapper macro
for hiding list in probe_cache.

Signed-off-by: Masami Hiramatsu 
---
 Changes in v10:
  - Splitted from "perf probe: Allow wildcard for cached events"
---
 tools/perf/util/probe-file.c |8 
 tools/perf/util/probe-file.h |2 ++
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index a6a2d60..503d7c2 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -546,7 +546,7 @@ probe_cache__find(struct probe_cache *pcache, struct 
perf_probe_event *pev)
if (!cmd)
return NULL;
 
-   list_for_each_entry(entry, >entries, node) {
+   for_each_probe_cache_entry(entry, pcache) {
if (pev->sdt) {
if (entry->pev.event &&
streql(entry->pev.event, pev->event) &&
@@ -576,7 +576,7 @@ probe_cache__find_by_name(struct probe_cache *pcache,
 {
struct probe_cache_entry *entry = NULL;
 
-   list_for_each_entry(entry, >entries, node) {
+   for_each_probe_cache_entry(entry, pcache) {
/* Hit if same event name or same command-string */
if (streql(entry->pev.group, group) &&
streql(entry->pev.event, event))
@@ -746,7 +746,7 @@ int probe_cache__commit(struct probe_cache *pcache)
if (ret < 0)
goto out;
 
-   list_for_each_entry(entry, >entries, node) {
+   for_each_probe_cache_entry(entry, pcache) {
ret = probe_cache_entry__write(entry, pcache->fd);
pr_debug("Cache committed: %d\n", ret);
if (ret < 0)
@@ -788,7 +788,7 @@ static int probe_cache__show_entries(struct probe_cache 
*pcache,
 {
struct probe_cache_entry *entry;
 
-   list_for_each_entry(entry, >entries, node) {
+   for_each_probe_cache_entry(entry, pcache) {
if (probe_cache_entry__compare(entry, filter))
printf("%s\n", entry->spev);
}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index b2b4c39..837f530 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -21,6 +21,8 @@ struct probe_cache {
 
 #define PF_FL_UPROBE   1
 #define PF_FL_RW   2
+#define for_each_probe_cache_entry(entry, pcache) \
+   list_for_each_entry(entry, >entries, node)
 
 /* probe-file.c depends on libelf */
 #ifdef HAVE_LIBELF_SUPPORT



[PATCH perf/core v11 22/23] perf build: Add sdt feature detection

2016-06-14 Thread Masami Hiramatsu
Will be used to define SDT events in perf test code.

Signed-off-by: Masami Hiramatsu 
---
 tools/build/Makefile.feature   |3 ++-
 tools/build/feature/Makefile   |6 +-
 tools/build/feature/test-all.c |5 +
 tools/build/feature/test-sdt.c |7 +++
 tools/perf/Makefile.perf   |3 +++
 tools/perf/config/Makefile |   10 ++
 tools/perf/tests/make  |3 ++-
 7 files changed, 34 insertions(+), 3 deletions(-)
 create mode 100644 tools/build/feature/test-sdt.c

diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 57c8f98..6bc7767 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -60,7 +60,8 @@ FEATURE_TESTS_BASIC :=\
zlib\
lzma\
get_cpuid   \
-   bpf
+   bpf \
+   sdt
 
 # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
 # of all feature tests
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 3d88f09..82d357f 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -43,7 +43,8 @@ FILES=\
test-zlib.bin   \
test-lzma.bin   \
test-bpf.bin\
-   test-get_cpuid.bin
+   test-get_cpuid.bin  \
+   test-sdt.bin
 
 FILES := $(addprefix $(OUTPUT),$(FILES))
 
@@ -205,6 +206,9 @@ $(OUTPUT)test-get_cpuid.bin:
 $(OUTPUT)test-bpf.bin:
$(BUILD)
 
+$(OUTPUT)test-sdt.bin:
+   $(BUILD)
+
 -include $(OUTPUT)*.d
 
 ###
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index a282e8c..f538c5f 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -137,6 +137,10 @@
 # include "test-libcrypto.c"
 #undef main
 
+#define main main_test_sdt
+# include "test-sdt.c"
+#undef main
+
 int main(int argc, char *argv[])
 {
main_test_libpython();
@@ -168,6 +172,7 @@ int main(int argc, char *argv[])
main_test_get_cpuid();
main_test_bpf();
main_test_libcrypto();
+   main_test_sdt();
 
return 0;
 }
diff --git a/tools/build/feature/test-sdt.c b/tools/build/feature/test-sdt.c
new file mode 100644
index 000..e4531a6
--- /dev/null
+++ b/tools/build/feature/test-sdt.c
@@ -0,0 +1,7 @@
+#include 
+
+int main(void)
+{
+   DTRACE_PROBE(provider, name);
+   return 0;
+}
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index bde8cba..a818388 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -81,6 +81,9 @@ include ../scripts/utilities.mak
 #
 # Define NO_LIBBPF if you do not want BPF support
 #
+# Define NO_SDT if you do not want to define SDT event in perf tools,
+# note that it doesn't disable SDT scanning support.
+#
 # Define FEATURES_DUMP to provide features detection dump file
 # and bypass the feature detection
 
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 098874b..f6c91a6 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -345,6 +345,16 @@ ifndef NO_LIBELF
   endif # NO_LIBBPF
 endif # NO_LIBELF
 
+ifndef NO_SDT
+  ifneq ($(feature-sdt), 1)
+msg := $(warning No sys/sdt.h found, no SDT events are defined, please 
install systemtap-sdt-devel or systemtap-sdt-dev);
+NO_SDT := 1;
+  else
+CFLAGS += -DHAVE_SDT_EVENT
+$(call detected,CONFIG_SDT_EVENT)
+  endif
+endif
+
 ifdef PERF_HAVE_JITDUMP
   ifndef NO_DWARF
 $(call detected,CONFIG_JITDUMP)
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index cac15d9..ac801be 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -81,6 +81,7 @@ make_no_libbionic   := NO_LIBBIONIC=1
 make_no_auxtrace:= NO_AUXTRACE=1
 make_no_libbpf := NO_LIBBPF=1
 make_no_libcrypto   := NO_LIBCRYPTO=1
+make_no_sdt:= NO_SDT=1
 make_tags   := tags
 make_cscope := cscope
 make_help   := help
@@ -104,7 +105,7 @@ make_minimal:= NO_LIBPERL=1 NO_LIBPYTHON=1 
NO_NEWT=1 NO_GTK2=1
 make_minimal+= NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
 make_minimal+= NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
 make_minimal+= NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
-make_minimal+= NO_LIBCRYPTO=1
+make_minimal+= NO_LIBCRYPTO=1 NO_SDT=1
 
 # $(run) contains all available tests
 run := make_pure



[PATCH perf/core v11 16/23] perf-list: Skip SDTs placed in invalid binaries

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

Skip SDTs placed in invalid (non-exist, or older version)
binaries. Note that perf-probe --cache --list and
perf-probe --cache --del still handle all the caches
including invalid binaries.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v7:
  - Validate build-id via sysfs if it is for kallsyms,
 Changes in v4:
  - Rename a parameter 'valid' to 'validonly' :)
---
 tools/perf/builtin-probe.c |2 +-
 tools/perf/util/build-id.c |   33 -
 tools/perf/util/build-id.h |2 +-
 tools/perf/util/parse-events.c |2 +-
 tools/perf/util/probe-file.c   |2 +-
 5 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 6c2c0d1..03ea72d 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)
struct str_node *nd;
int ret;
 
-   bidlist = build_id_cache__list_all();
+   bidlist = build_id_cache__list_all(false);
if (!bidlist) {
ret = -errno;
pr_debug("Failed to get buildids: %d\n", ret);
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 95d4490..a28ef39 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -206,6 +206,31 @@ out:
return ret;
 }
 
+/* Check if the given build_id cache is valid on current running system */
+static bool build_id_cache__valid_id(char *sbuild_id)
+{
+   char real_sbuild_id[SBUILD_ID_SIZE] = "";
+   char *pathname;
+   int ret = 0;
+   bool result = false;
+
+   pathname = build_id_cache__origname(sbuild_id);
+   if (!pathname)
+   return false;
+
+   if (!strcmp(pathname, DSO__NAME_KALLSYMS))
+   ret = sysfs__sprintf_build_id("/", real_sbuild_id);
+   else if (pathname[0] == '/')
+   ret = filename__sprintf_build_id(pathname, real_sbuild_id);
+   else
+   ret = -EINVAL;  /* Should we support other special DSO cache? */
+   if (ret >= 0)
+   result = (strcmp(sbuild_id, real_sbuild_id) == 0);
+   free(pathname);
+
+   return result;
+}
+
 static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
 {
return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
@@ -433,13 +458,17 @@ static bool lsdir_bid_tail_filter(const char *name 
__maybe_unused,
return (i == SBUILD_ID_SIZE - 3) && (d->d_name[i] == '\0');
 }
 
-struct strlist *build_id_cache__list_all(void)
+struct strlist *build_id_cache__list_all(bool validonly)
 {
struct strlist *toplist, *linklist = NULL, *bidlist;
struct str_node *nd, *nd2;
char *topdir, *linkdir = NULL;
char sbuild_id[SBUILD_ID_SIZE];
 
+   /* for filename__ functions */
+   if (validonly)
+   symbol__init(NULL);
+
/* Open the top-level directory */
if (asprintf(, "%s/.build-id/", buildid_dir) < 0)
return NULL;
@@ -470,6 +499,8 @@ struct strlist *build_id_cache__list_all(void)
if (snprintf(sbuild_id, SBUILD_ID_SIZE, "%s%s",
 nd->s, nd2->s) != SBUILD_ID_SIZE - 1)
goto err_out;
+   if (validonly && !build_id_cache__valid_id(sbuild_id))
+   continue;
if (strlist__add(bidlist, sbuild_id) < 0)
goto err_out;
}
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index b742e27..64e740f 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -34,7 +34,7 @@ char *build_id_cache__origname(const char *sbuild_id);
 char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
   bool is_kallsyms, bool is_vdso);
-struct strlist *build_id_cache__list_all(void);
+struct strlist *build_id_cache__list_all(bool validonly);
 int build_id_cache__list_build_ids(const char *pathname,
   struct strlist **result);
 bool build_id_cache__cached(const char *sbuild_id);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 05bd505..54a4e2b 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -2002,7 +2002,7 @@ void print_sdt_events(const char *subsys_glob, const char 
*event_glob,
pr_debug("Failed to allocate new strlist for SDT\n");
return;
}
-   bidlist = build_id_cache__list_all();
+   bidlist = build_id_cache__list_all(true);
if (!bidlist) {
pr_debug("Failed to get buildids: %d\n", errno);
return;
diff --git a/tools/perf/util/probe-file.c 

[PATCH perf/core v11 20/23] perf probe: Support @BUILDID or @FILE suffix for SDT events

2016-06-14 Thread Masami Hiramatsu
Support @BUILDID or @FILE suffix for SDT events. This allows
perf to add probes on SDTs/pre-cached events on given FILE
or the file which has given BUILDID (also, this complements
BUILDID.)
For example, both gcc and libstdc++ has same SDTs as below.
If you would like to add a probe on sdt_libstdcxx:catch on gcc,
you can do as below.

  
  # perf list sdt | tail -n 6
sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27)   [SDT event]
sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
  # perf probe -a %sdt_libstdcxx:catch@0cc
  Added new event:
sdt_libstdcxx:catch  (on %catch in /usr/bin/gcc)

  You can now use it in all perf tools, such as:

perf record -e sdt_libstdcxx:catch -aR sleep 1
  

Signed-off-by: Masami Hiramatsu 
---
 tools/perf/util/build-id.c|   43 +
 tools/perf/util/build-id.h|1 +
 tools/perf/util/probe-event.c |   17 ++--
 3 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index a28ef39..7b78a33 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -523,6 +523,49 @@ err_out:
goto out_free;
 }
 
+static bool str_is_build_id(const char *maybe_sbuild_id, size_t len)
+{
+   size_t i;
+
+   for (i = 0; i < len; i++) {
+   if (!isxdigit(maybe_sbuild_id[i]))
+   return false;
+   }
+   return true;
+}
+
+/* Return the valid complete build-id */
+char *build_id_cache__complement(const char *incomplete_sbuild_id)
+{
+   struct strlist *bidlist;
+   struct str_node *nd, *cand = NULL;
+   char *sbuild_id = NULL;
+   size_t len = strlen(incomplete_sbuild_id);
+
+   if (len >= SBUILD_ID_SIZE ||
+   !str_is_build_id(incomplete_sbuild_id, len))
+   return NULL;
+
+   bidlist = build_id_cache__list_all(true);
+   if (!bidlist)
+   return NULL;
+
+   strlist__for_each(nd, bidlist) {
+   if (strncmp(nd->s, incomplete_sbuild_id, len) != 0)
+   continue;
+   if (cand) { /* Error: There are more than 2 candidates. */
+   cand = NULL;
+   break;
+   }
+   cand = nd;
+   }
+   if (cand)
+   sbuild_id = strdup(cand->s);
+   strlist__delete(bidlist);
+
+   return sbuild_id;
+}
+
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
   bool is_kallsyms, bool is_vdso)
 {
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 64e740f..d279906 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char 
*bf, size_t size);
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
   bool is_kallsyms, bool is_vdso);
 struct strlist *build_id_cache__list_all(bool validonly);
+char *build_id_cache__complement(const char *incomplete_sbuild_id);
 int build_id_cache__list_build_ids(const char *pathname,
   struct strlist **result);
 bool build_id_cache__cached(const char *sbuild_id);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 81e22f1..fa3cbb3 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1253,8 +1253,21 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
ptr = strpbrk(arg, ";=@+%");
if (pev->sdt) {
if (ptr) {
-   semantic_error("%s must contain only an SDT event 
name.\n", arg);
-   return -EINVAL;
+   if (*ptr != '@') {
+   semantic_error("%s must be an SDT name.\n",
+  arg);
+   return -EINVAL;
+   }
+   /* This must be a target file name or build id */
+   tmp = build_id_cache__complement(ptr + 1);
+   if (tmp) {
+   pev->target = build_id_cache__origname(tmp);
+   free(tmp);
+   } else
+   pev->target = strdup(ptr + 1);
+   if (!pev->target)
+   return -ENOMEM;
+   *ptr = '\0';
}
ret = parse_perf_probe_event_name(, pev);
if (ret == 0) {



[PATCH perf/core v11 11/23] perf/sdt: ELF support for SDT

2016-06-14 Thread Masami Hiramatsu
From: Hemant Kumar 

This patch serves the initial support to identify and list SDT events in 
binaries.
When programs containing SDT markers are compiled, gcc with the help of 
assembler
directives identifies them and places them in the section ".note.stapsdt". To 
find
these markers from the binaries, one needs to traverse through this section and
parse the relevant details like the name, type and location of the marker. Also,
the original location could be skewed due to the effect of prelinking. If that 
is
the case, the locations need to be adjusted.

The functions in this patch open a given ELF, find out the SDT section, parse 
the
relevant details, adjust the location (if necessary) and populate them in a 
list.

A typical note entry in ".note.stapsdt" section is as follows :


 |--nhdr.n_namesz--|

|  nhdr  | "stapsdt"   |
-   |--|
 |  |  |
 |  |   |
nhdr.n_descsize |  "provider_name"   "note_name"   |
 |  ||
-   |--|
|  nhdr  | "stapsdt"   |
|...

The above shows an excerpt from the section ".note.stapsdt".
'nhdr' is a structure which has the note name size (n_namesz), note
description size (n_desc_sz) and note type (n_type). So, in order to
parse the note note info, we need nhdr to tell us where to start from.
As can be seen from , the name of the SDT notes given is "stapsdt".
But this is not the identifier of the note.
After that, we go to description of the note to find out its location, the
address of the ".stapsdt.base" section and the semaphore address.
Then, we find the provider name and the SDT marker name and then follow the
arguments.

Signed-off-by: Hemant Kumar 
Reviewed-by: Masami Hiramatsu 
Acked-by: Namhyung Kim 
---
 tools/perf/util/symbol-elf.c |  252 ++
 tools/perf/util/symbol.h |   22 
 2 files changed, 274 insertions(+)

diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 87a297d..e74ce17 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1781,6 +1781,258 @@ void kcore_extract__delete(struct kcore_extract *kce)
unlink(kce->extract_filename);
 }
 
+/**
+ * populate_sdt_note : Parse raw data and identify SDT note
+ * @elf: elf of the opened file
+ * @data: raw data of a section with description offset applied
+ * @len: note description size
+ * @type: type of the note
+ * @sdt_notes: List to add the SDT note
+ *
+ * Responsible for parsing the @data in section .note.stapsdt in @elf and
+ * if its an SDT note, it appends to @sdt_notes list.
+ */
+static int populate_sdt_note(Elf **elf, const char *data, size_t len,
+struct list_head *sdt_notes)
+{
+   const char *provider, *name;
+   struct sdt_note *tmp = NULL;
+   GElf_Ehdr ehdr;
+   GElf_Addr base_off = 0;
+   GElf_Shdr shdr;
+   int ret = -EINVAL;
+
+   union {
+   Elf64_Addr a64[NR_ADDR];
+   Elf32_Addr a32[NR_ADDR];
+   } buf;
+
+   Elf_Data dst = {
+   .d_buf = , .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
+   .d_size = gelf_fsize((*elf), ELF_T_ADDR, NR_ADDR, EV_CURRENT),
+   .d_off = 0, .d_align = 0
+   };
+   Elf_Data src = {
+   .d_buf = (void *) data, .d_type = ELF_T_ADDR,
+   .d_version = EV_CURRENT, .d_size = dst.d_size, .d_off = 0,
+   .d_align = 0
+   };
+
+   tmp = (struct sdt_note *)calloc(1, sizeof(struct sdt_note));
+   if (!tmp) {
+   ret = -ENOMEM;
+   goto out_err;
+   }
+
+   INIT_LIST_HEAD(>note_list);
+
+   if (len < dst.d_size + 3)
+   goto out_free_note;
+
+   /* Translation from file representation to memory representation */
+   if (gelf_xlatetom(*elf, , ,
+ elf_getident(*elf, NULL)[EI_DATA]) == NULL) {
+   pr_err("gelf_xlatetom : %s\n", elf_errmsg(-1));
+   goto out_free_note;
+   }
+
+   /* Populate the fields of sdt_note */
+   provider = data + dst.d_size;
+
+   name = (const char *)memchr(provider, '\0', data + len - provider);
+   if (name++ == NULL)
+   goto out_free_note;
+
+   tmp->provider = strdup(provider);
+   if (!tmp->provider) {
+   ret = -ENOMEM;
+   goto out_free_note;
+   }
+   tmp->name = strdup(name);
+   if (!tmp->name) {
+   ret = -ENOMEM;
+   goto out_free_prov;
+   }
+
+   if (gelf_getclass(*elf) == ELFCLASS32) {
+   memcpy(>addr, , 3 * 

[PATCH perf/core v11 11/23] perf/sdt: ELF support for SDT

2016-06-14 Thread Masami Hiramatsu
From: Hemant Kumar 

This patch serves the initial support to identify and list SDT events in 
binaries.
When programs containing SDT markers are compiled, gcc with the help of 
assembler
directives identifies them and places them in the section ".note.stapsdt". To 
find
these markers from the binaries, one needs to traverse through this section and
parse the relevant details like the name, type and location of the marker. Also,
the original location could be skewed due to the effect of prelinking. If that 
is
the case, the locations need to be adjusted.

The functions in this patch open a given ELF, find out the SDT section, parse 
the
relevant details, adjust the location (if necessary) and populate them in a 
list.

A typical note entry in ".note.stapsdt" section is as follows :


 |--nhdr.n_namesz--|

|  nhdr  | "stapsdt"   |
-   |--|
 |  |  |
 |  |   |
nhdr.n_descsize |  "provider_name"   "note_name"   |
 |  ||
-   |--|
|  nhdr  | "stapsdt"   |
|...

The above shows an excerpt from the section ".note.stapsdt".
'nhdr' is a structure which has the note name size (n_namesz), note
description size (n_desc_sz) and note type (n_type). So, in order to
parse the note note info, we need nhdr to tell us where to start from.
As can be seen from , the name of the SDT notes given is "stapsdt".
But this is not the identifier of the note.
After that, we go to description of the note to find out its location, the
address of the ".stapsdt.base" section and the semaphore address.
Then, we find the provider name and the SDT marker name and then follow the
arguments.

Signed-off-by: Hemant Kumar 
Reviewed-by: Masami Hiramatsu 
Acked-by: Namhyung Kim 
---
 tools/perf/util/symbol-elf.c |  252 ++
 tools/perf/util/symbol.h |   22 
 2 files changed, 274 insertions(+)

diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 87a297d..e74ce17 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1781,6 +1781,258 @@ void kcore_extract__delete(struct kcore_extract *kce)
unlink(kce->extract_filename);
 }
 
+/**
+ * populate_sdt_note : Parse raw data and identify SDT note
+ * @elf: elf of the opened file
+ * @data: raw data of a section with description offset applied
+ * @len: note description size
+ * @type: type of the note
+ * @sdt_notes: List to add the SDT note
+ *
+ * Responsible for parsing the @data in section .note.stapsdt in @elf and
+ * if its an SDT note, it appends to @sdt_notes list.
+ */
+static int populate_sdt_note(Elf **elf, const char *data, size_t len,
+struct list_head *sdt_notes)
+{
+   const char *provider, *name;
+   struct sdt_note *tmp = NULL;
+   GElf_Ehdr ehdr;
+   GElf_Addr base_off = 0;
+   GElf_Shdr shdr;
+   int ret = -EINVAL;
+
+   union {
+   Elf64_Addr a64[NR_ADDR];
+   Elf32_Addr a32[NR_ADDR];
+   } buf;
+
+   Elf_Data dst = {
+   .d_buf = , .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
+   .d_size = gelf_fsize((*elf), ELF_T_ADDR, NR_ADDR, EV_CURRENT),
+   .d_off = 0, .d_align = 0
+   };
+   Elf_Data src = {
+   .d_buf = (void *) data, .d_type = ELF_T_ADDR,
+   .d_version = EV_CURRENT, .d_size = dst.d_size, .d_off = 0,
+   .d_align = 0
+   };
+
+   tmp = (struct sdt_note *)calloc(1, sizeof(struct sdt_note));
+   if (!tmp) {
+   ret = -ENOMEM;
+   goto out_err;
+   }
+
+   INIT_LIST_HEAD(>note_list);
+
+   if (len < dst.d_size + 3)
+   goto out_free_note;
+
+   /* Translation from file representation to memory representation */
+   if (gelf_xlatetom(*elf, , ,
+ elf_getident(*elf, NULL)[EI_DATA]) == NULL) {
+   pr_err("gelf_xlatetom : %s\n", elf_errmsg(-1));
+   goto out_free_note;
+   }
+
+   /* Populate the fields of sdt_note */
+   provider = data + dst.d_size;
+
+   name = (const char *)memchr(provider, '\0', data + len - provider);
+   if (name++ == NULL)
+   goto out_free_note;
+
+   tmp->provider = strdup(provider);
+   if (!tmp->provider) {
+   ret = -ENOMEM;
+   goto out_free_note;
+   }
+   tmp->name = strdup(name);
+   if (!tmp->name) {
+   ret = -ENOMEM;
+   goto out_free_prov;
+   }
+
+   if (gelf_getclass(*elf) == ELFCLASS32) {
+   memcpy(>addr, , 3 * sizeof(Elf32_Addr));
+   tmp->bit32 = true;
+   } else {
+   memcpy(>addr, 

[PATCH perf/core v11 15/23] perf-list: Show SDT and pre-cached events

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

Show SDT and pre-cached events by perf-list with "sdt". This also
shows the binary and build-id where the events are placed only
when there are same name events on different binaries.
e.g.
  
  # perf list sdt

  List of pre-defined events (to be used in -e):

sdt_libc:lll_futex_wake[SDT event]
sdt_libc:lll_lock_wait_private [SDT event]
sdt_libc:longjmp   [SDT event]
sdt_libc:longjmp_target[SDT event]
  ...
sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27)   [SDT event]
sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
  

The binary path and build-id are shown in below format;

  :@()

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v9:
  - Update list_usage too. (Thanks Hemant!)
 Changes in v5:
  - Fix a build error for minimal option.

 Changes in v4:
  - Update patch description.
  - Change event list format.
---
 tools/perf/builtin-list.c  |6 ++-
 tools/perf/util/parse-events.c |   82 
 tools/perf/util/parse-events.h |2 +
 tools/perf/util/probe-file.h   |9 
 4 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 5e22db4..88ee419 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -25,7 +25,7 @@ int cmd_list(int argc, const char **argv, const char *prefix 
__maybe_unused)
OPT_END()
};
const char * const list_usage[] = {
-   "perf list [hw|sw|cache|tracepoint|pmu|event_glob]",
+   "perf list [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
NULL
};
 
@@ -62,6 +62,8 @@ int cmd_list(int argc, const char **argv, const char *prefix 
__maybe_unused)
print_hwcache_events(NULL, raw_dump);
else if (strcmp(argv[i], "pmu") == 0)
print_pmu_events(NULL, raw_dump);
+   else if (strcmp(argv[i], "sdt") == 0)
+   print_sdt_events(NULL, NULL, raw_dump);
else if ((sep = strchr(argv[i], ':')) != NULL) {
int sep_idx;
 
@@ -76,6 +78,7 @@ int cmd_list(int argc, const char **argv, const char *prefix 
__maybe_unused)
 
s[sep_idx] = '\0';
print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
+   print_sdt_events(s, s + sep_idx + 1, raw_dump);
free(s);
} else {
if (asprintf(, "*%s*", argv[i]) < 0) {
@@ -89,6 +92,7 @@ int cmd_list(int argc, const char **argv, const char *prefix 
__maybe_unused)
print_hwcache_events(s, raw_dump);
print_pmu_events(s, raw_dump);
print_tracepoint_events(NULL, s, raw_dump);
+   print_sdt_events(NULL, s, raw_dump);
free(s);
}
}
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d15e335..05bd505 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -20,6 +20,7 @@
 #include "pmu.h"
 #include "thread_map.h"
 #include "cpumap.h"
+#include "probe-file.h"
 #include "asm/bug.h"
 
 #define MAX_NAME_LEN 100
@@ -1984,6 +1985,85 @@ static bool is_event_supported(u8 type, unsigned config)
return ret;
 }
 
+void print_sdt_events(const char *subsys_glob, const char *event_glob,
+ bool name_only)
+{
+   struct probe_cache *pcache;
+   struct probe_cache_entry *ent;
+   struct strlist *bidlist, *sdtlist;
+   struct strlist_config cfg = {.dont_dupstr = true};
+   struct str_node *nd, *nd2;
+   char *buf, *path, *ptr = NULL;
+   bool show_detail = false;
+   int ret;
+
+   sdtlist = strlist__new(NULL, );
+   if (!sdtlist) {
+   pr_debug("Failed to allocate new strlist for SDT\n");
+   return;
+   }
+   bidlist = build_id_cache__list_all();
+   if (!bidlist) {
+   pr_debug("Failed to get buildids: %d\n", errno);
+   return;
+   }
+   strlist__for_each(nd, bidlist) {
+   pcache = probe_cache__new(nd->s);
+   if (!pcache)
+   continue;
+   list_for_each_entry(ent, >entries, node) {
+   if (!ent->sdt)
+   continue;
+   if (subsys_glob &&
+   !strglobmatch(ent->pev.group, subsys_glob))
+   continue;
+ 

[PATCH perf/core v11 13/23] perf buildid-cache: Scan and import user SDT events to probe cache

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

perf buildid-cache --add  scans given binary and add
the SDT events to probe cache. "sdt_" prefix is appended for
all SDT providers to avoid event-name clash with other pre-defined
events. It is possible to use the cached SDT events as other cached
events, via perf probe --add "sdt_:=".

e.g.
  
  # perf buildid-cache --add /lib/libc-2.17.so
  # perf probe --cache --list | head -n 5
  /usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392):
  sdt_libc:setjmp=setjmp
  sdt_libc:longjmp=longjmp
  sdt_libc:longjmp_target=longjmp_target
  sdt_libc:memory_heap_new=memory_heap_new
  # perf probe -x /usr/lib/libc-2.17.so \
-a sdt_libc:memory_heap_new=memory_heap_new
  Added new event:
sdt_libc:memory_heap_new (on memory_heap_new
   in /usr/lib/libc-2.17.so)

  You can now use it in all perf tools, such as:

  perf record -e sdt_libc:memory_heap_new -aR sleep 1

  # perf probe -l
sdt_libc:memory_heap_new (on new_heap+183 in /usr/lib/libc-2.17.so)
  

Note that SDT event entries in probe-cache file is somewhat different
from normal cached events. Normal one starts with "#", but SDTs are
starting with "%".

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v11:
  - Warn if SDT scanning/updating are failed.
 Changes in v10:
  - Update Documentation/perf-buildid-cache.txt too.
 Changes in v4:
  - Fix a bug to copy correct group name to entries.
  - Fix to consolidate same-name entries.
---
 tools/perf/Documentation/perf-buildid-cache.txt |3 +
 tools/perf/util/build-id.c  |   30 ++
 tools/perf/util/probe-file.c|   69 ++-
 tools/perf/util/probe-file.h|2 +
 4 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Documentation/perf-buildid-cache.txt 
b/tools/perf/Documentation/perf-buildid-cache.txt
index dd07b55..058064d 100644
--- a/tools/perf/Documentation/perf-buildid-cache.txt
+++ b/tools/perf/Documentation/perf-buildid-cache.txt
@@ -15,6 +15,9 @@ DESCRIPTION
 This command manages the build-id cache. It can add, remove, update and purge
 files to/from the cache. In the future it should as well set upper limits for
 the space used by the cache, etc.
+This also scans the target binary for SDT (Statically Defined Tracing) and
+record it along with the buildid-cache, which will be used by perf-probe.
+For more details, see linkperf:perf-probe[1].
 
 OPTIONS
 ---
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 0d6093c..95d4490 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -17,6 +17,7 @@
 #include "tool.h"
 #include "header.h"
 #include "vdso.h"
+#include "probe-file.h"
 
 
 static bool no_buildid_cache;
@@ -532,6 +533,30 @@ int build_id_cache__list_build_ids(const char *pathname,
return ret;
 }
 
+#ifdef HAVE_LIBELF_SUPPORT
+static int build_id_cache__add_sdt_cache(const char *sbuild_id,
+ const char *realname)
+{
+   struct probe_cache *cache;
+   int ret;
+
+   cache = probe_cache__new(sbuild_id);
+   if (!cache)
+   return -1;
+
+   ret = probe_cache__scan_sdt(cache, realname);
+   if (ret >= 0) {
+   pr_debug("Found %d SDTs in %s\n", ret, realname);
+   if (probe_cache__commit(cache) < 0)
+   ret = -1;
+   }
+   probe_cache__delete(cache);
+   return ret;
+}
+#else
+#define build_id_cache__add_sdt_cache(sbuild_id, realname) (0)
+#endif
+
 int build_id_cache__add_s(const char *sbuild_id, const char *name,
  bool is_kallsyms, bool is_vdso)
 {
@@ -589,6 +614,11 @@ int build_id_cache__add_s(const char *sbuild_id, const 
char *name,
 
if (symlink(tmp, linkname) == 0)
err = 0;
+
+   /* Update SDT cache : error is just warned */
+   if (build_id_cache__add_sdt_cache(sbuild_id, realname) < 0)
+   pr_debug("Failed to update/scan SDT cache for %s\n", realname);
+
 out_free:
if (!is_kallsyms)
free(realname);
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index f8f710e..0f544bd 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -434,12 +434,15 @@ static int probe_cache__load(struct probe_cache *pcache)
p = strchr(buf, '\n');
if (p)
*p = '\0';
-   if (buf[0] == '#') {/* #perf_probe_event */
+   /* #perf_probe_event or %sdt_event */
+   if (buf[0] == '#' || buf[0] == '%') {
entry = probe_cache_entry__new(NULL);
if (!entry) {
ret = -ENOMEM;
goto out;
}
+

[PATCH perf/core v11 10/23] perf probe: Remove caches when --cache is given

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

perf-probe --del removes caches when --cache is given.
Note that the delete pattern is not same as normal events.

If you cached probes with event name, --del "eventname"
works as expected. However, if you skipped it, the cached
probes doesn't have actual event name. In that case
 --del "probe-desc" is required (wildcard is acceptable).
For example a cache entry has the probe-desc "vfs_read $params",
you can remove it with --del 'vfs_read*'.

  -
  # perf probe --cache --list
  /[kernel.kallsyms] (1466a0a250b5d0070c6d0f03c5fed30b237970a1):
  vfs_read $params
  /usr/lib64/libc-2.17.so (c31ffe7942bfd77b2fca8f9bd5709d387a86d3bc):
  getaddrinfo $params

  # perf probe --cache --del vfs_read\*
  Removed cached event: probe:vfs_read

  # perf probe --cache --list
  /[kernel.kallsyms] (1466a0a250b5d0070c6d0f03c5fed30b237970a1):
  /usr/lib64/libc-2.17.so (c31ffe7942bfd77b2fca8f9bd5709d387a86d3bc):
  getaddrinfo $params
  -

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v11:
  - Fix to check the result of purging cache entries.
  - Rename probe_cache__remove_entries to probe_cache__filter_purge.
 Changes in v9:
  - Fix to show which event is deleted (Thanks Hemant!)
 Changes in v4:
  - move del_perf_probe_caches() into builtin-probe.c since
command-line related delete procedure is there now.
---
 tools/perf/Documentation/perf-probe.txt |1 +
 tools/perf/builtin-probe.c  |   29 +
 tools/perf/util/probe-file.c|   36 ---
 tools/perf/util/probe-file.h|2 ++
 4 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index 5a70d45..8d09173 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -116,6 +116,7 @@ OPTIONS
(With --add) Cache the probes. Any events which successfully added
are also stored in the cache file.
(With --list) Show cached probes.
+   (With --del) Remove cached probes.
 
 --max-probes=NUM::
Set the maximum number of probe points for an event. Default is 128.
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 53e380c0e..6c2c0d1 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -363,6 +363,32 @@ out_cleanup:
return ret;
 }
 
+static int del_perf_probe_caches(struct strfilter *filter)
+{
+   struct probe_cache *cache;
+   struct strlist *bidlist;
+   struct str_node *nd;
+   int ret;
+
+   bidlist = build_id_cache__list_all();
+   if (!bidlist) {
+   ret = -errno;
+   pr_debug("Failed to get buildids: %d\n", ret);
+   return ret ?: -ENOMEM;
+   }
+
+   strlist__for_each(nd, bidlist) {
+   cache = probe_cache__new(nd->s);
+   if (!cache)
+   continue;
+   if (probe_cache__filter_purge(cache, filter) < 0 ||
+   probe_cache__commit(cache) < 0)
+   pr_warning("Failed to remove entries for %s\n", nd->s);
+   probe_cache__delete(cache);
+   }
+   return 0;
+}
+
 static int perf_del_probe_events(struct strfilter *filter)
 {
int ret, ret2, ufd = -1, kfd = -1;
@@ -375,6 +401,9 @@ static int perf_del_probe_events(struct strfilter *filter)
 
pr_debug("Delete filter: \'%s\'\n", str);
 
+   if (probe_conf.cache)
+   return del_perf_probe_caches(filter);
+
/* Get current event names */
ret = probe_file__open_both(, , PF_FL_RW);
if (ret < 0)
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 47e0e95..f8f710e 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -684,20 +684,40 @@ out:
return ret;
 }
 
+static bool probe_cache_entry__compare(struct probe_cache_entry *entry,
+  struct strfilter *filter)
+{
+   char buf[128], *ptr = entry->spev;
+
+   if (entry->pev.event) {
+   snprintf(buf, 128, "%s:%s", entry->pev.group, entry->pev.event);
+   ptr = buf;
+   }
+   return strfilter__compare(filter, ptr);
+}
+
+int probe_cache__filter_purge(struct probe_cache *pcache,
+ struct strfilter *filter)
+{
+   struct probe_cache_entry *entry, *tmp;
+
+   list_for_each_entry_safe(entry, tmp, >entries, node) {
+   if (probe_cache_entry__compare(entry, filter)) {
+   pr_info("Removed cached event: %s\n", entry->spev);
+   list_del_init(>node);
+   probe_cache_entry__delete(entry);
+   }
+   }
+   return 0;
+}
+
 static int probe_cache__show_entries(struct 

[PATCH perf/core v11 15/23] perf-list: Show SDT and pre-cached events

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

Show SDT and pre-cached events by perf-list with "sdt". This also
shows the binary and build-id where the events are placed only
when there are same name events on different binaries.
e.g.
  
  # perf list sdt

  List of pre-defined events (to be used in -e):

sdt_libc:lll_futex_wake[SDT event]
sdt_libc:lll_lock_wait_private [SDT event]
sdt_libc:longjmp   [SDT event]
sdt_libc:longjmp_target[SDT event]
  ...
sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27)   [SDT event]
sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
  

The binary path and build-id are shown in below format;

  :@()

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v9:
  - Update list_usage too. (Thanks Hemant!)
 Changes in v5:
  - Fix a build error for minimal option.

 Changes in v4:
  - Update patch description.
  - Change event list format.
---
 tools/perf/builtin-list.c  |6 ++-
 tools/perf/util/parse-events.c |   82 
 tools/perf/util/parse-events.h |2 +
 tools/perf/util/probe-file.h   |9 
 4 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 5e22db4..88ee419 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -25,7 +25,7 @@ int cmd_list(int argc, const char **argv, const char *prefix 
__maybe_unused)
OPT_END()
};
const char * const list_usage[] = {
-   "perf list [hw|sw|cache|tracepoint|pmu|event_glob]",
+   "perf list [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
NULL
};
 
@@ -62,6 +62,8 @@ int cmd_list(int argc, const char **argv, const char *prefix 
__maybe_unused)
print_hwcache_events(NULL, raw_dump);
else if (strcmp(argv[i], "pmu") == 0)
print_pmu_events(NULL, raw_dump);
+   else if (strcmp(argv[i], "sdt") == 0)
+   print_sdt_events(NULL, NULL, raw_dump);
else if ((sep = strchr(argv[i], ':')) != NULL) {
int sep_idx;
 
@@ -76,6 +78,7 @@ int cmd_list(int argc, const char **argv, const char *prefix 
__maybe_unused)
 
s[sep_idx] = '\0';
print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
+   print_sdt_events(s, s + sep_idx + 1, raw_dump);
free(s);
} else {
if (asprintf(, "*%s*", argv[i]) < 0) {
@@ -89,6 +92,7 @@ int cmd_list(int argc, const char **argv, const char *prefix 
__maybe_unused)
print_hwcache_events(s, raw_dump);
print_pmu_events(s, raw_dump);
print_tracepoint_events(NULL, s, raw_dump);
+   print_sdt_events(NULL, s, raw_dump);
free(s);
}
}
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d15e335..05bd505 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -20,6 +20,7 @@
 #include "pmu.h"
 #include "thread_map.h"
 #include "cpumap.h"
+#include "probe-file.h"
 #include "asm/bug.h"
 
 #define MAX_NAME_LEN 100
@@ -1984,6 +1985,85 @@ static bool is_event_supported(u8 type, unsigned config)
return ret;
 }
 
+void print_sdt_events(const char *subsys_glob, const char *event_glob,
+ bool name_only)
+{
+   struct probe_cache *pcache;
+   struct probe_cache_entry *ent;
+   struct strlist *bidlist, *sdtlist;
+   struct strlist_config cfg = {.dont_dupstr = true};
+   struct str_node *nd, *nd2;
+   char *buf, *path, *ptr = NULL;
+   bool show_detail = false;
+   int ret;
+
+   sdtlist = strlist__new(NULL, );
+   if (!sdtlist) {
+   pr_debug("Failed to allocate new strlist for SDT\n");
+   return;
+   }
+   bidlist = build_id_cache__list_all();
+   if (!bidlist) {
+   pr_debug("Failed to get buildids: %d\n", errno);
+   return;
+   }
+   strlist__for_each(nd, bidlist) {
+   pcache = probe_cache__new(nd->s);
+   if (!pcache)
+   continue;
+   list_for_each_entry(ent, >entries, node) {
+   if (!ent->sdt)
+   continue;
+   if (subsys_glob &&
+   !strglobmatch(ent->pev.group, subsys_glob))
+   continue;
+   if (event_glob &&
+   

[PATCH perf/core v11 13/23] perf buildid-cache: Scan and import user SDT events to probe cache

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

perf buildid-cache --add  scans given binary and add
the SDT events to probe cache. "sdt_" prefix is appended for
all SDT providers to avoid event-name clash with other pre-defined
events. It is possible to use the cached SDT events as other cached
events, via perf probe --add "sdt_:=".

e.g.
  
  # perf buildid-cache --add /lib/libc-2.17.so
  # perf probe --cache --list | head -n 5
  /usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392):
  sdt_libc:setjmp=setjmp
  sdt_libc:longjmp=longjmp
  sdt_libc:longjmp_target=longjmp_target
  sdt_libc:memory_heap_new=memory_heap_new
  # perf probe -x /usr/lib/libc-2.17.so \
-a sdt_libc:memory_heap_new=memory_heap_new
  Added new event:
sdt_libc:memory_heap_new (on memory_heap_new
   in /usr/lib/libc-2.17.so)

  You can now use it in all perf tools, such as:

  perf record -e sdt_libc:memory_heap_new -aR sleep 1

  # perf probe -l
sdt_libc:memory_heap_new (on new_heap+183 in /usr/lib/libc-2.17.so)
  

Note that SDT event entries in probe-cache file is somewhat different
from normal cached events. Normal one starts with "#", but SDTs are
starting with "%".

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v11:
  - Warn if SDT scanning/updating are failed.
 Changes in v10:
  - Update Documentation/perf-buildid-cache.txt too.
 Changes in v4:
  - Fix a bug to copy correct group name to entries.
  - Fix to consolidate same-name entries.
---
 tools/perf/Documentation/perf-buildid-cache.txt |3 +
 tools/perf/util/build-id.c  |   30 ++
 tools/perf/util/probe-file.c|   69 ++-
 tools/perf/util/probe-file.h|2 +
 4 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Documentation/perf-buildid-cache.txt 
b/tools/perf/Documentation/perf-buildid-cache.txt
index dd07b55..058064d 100644
--- a/tools/perf/Documentation/perf-buildid-cache.txt
+++ b/tools/perf/Documentation/perf-buildid-cache.txt
@@ -15,6 +15,9 @@ DESCRIPTION
 This command manages the build-id cache. It can add, remove, update and purge
 files to/from the cache. In the future it should as well set upper limits for
 the space used by the cache, etc.
+This also scans the target binary for SDT (Statically Defined Tracing) and
+record it along with the buildid-cache, which will be used by perf-probe.
+For more details, see linkperf:perf-probe[1].
 
 OPTIONS
 ---
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 0d6093c..95d4490 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -17,6 +17,7 @@
 #include "tool.h"
 #include "header.h"
 #include "vdso.h"
+#include "probe-file.h"
 
 
 static bool no_buildid_cache;
@@ -532,6 +533,30 @@ int build_id_cache__list_build_ids(const char *pathname,
return ret;
 }
 
+#ifdef HAVE_LIBELF_SUPPORT
+static int build_id_cache__add_sdt_cache(const char *sbuild_id,
+ const char *realname)
+{
+   struct probe_cache *cache;
+   int ret;
+
+   cache = probe_cache__new(sbuild_id);
+   if (!cache)
+   return -1;
+
+   ret = probe_cache__scan_sdt(cache, realname);
+   if (ret >= 0) {
+   pr_debug("Found %d SDTs in %s\n", ret, realname);
+   if (probe_cache__commit(cache) < 0)
+   ret = -1;
+   }
+   probe_cache__delete(cache);
+   return ret;
+}
+#else
+#define build_id_cache__add_sdt_cache(sbuild_id, realname) (0)
+#endif
+
 int build_id_cache__add_s(const char *sbuild_id, const char *name,
  bool is_kallsyms, bool is_vdso)
 {
@@ -589,6 +614,11 @@ int build_id_cache__add_s(const char *sbuild_id, const 
char *name,
 
if (symlink(tmp, linkname) == 0)
err = 0;
+
+   /* Update SDT cache : error is just warned */
+   if (build_id_cache__add_sdt_cache(sbuild_id, realname) < 0)
+   pr_debug("Failed to update/scan SDT cache for %s\n", realname);
+
 out_free:
if (!is_kallsyms)
free(realname);
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index f8f710e..0f544bd 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -434,12 +434,15 @@ static int probe_cache__load(struct probe_cache *pcache)
p = strchr(buf, '\n');
if (p)
*p = '\0';
-   if (buf[0] == '#') {/* #perf_probe_event */
+   /* #perf_probe_event or %sdt_event */
+   if (buf[0] == '#' || buf[0] == '%') {
entry = probe_cache_entry__new(NULL);
if (!entry) {
ret = -ENOMEM;
goto out;
}
+   if (buf[0] == '%')
+   entry->sdt = true;
  

[PATCH perf/core v11 10/23] perf probe: Remove caches when --cache is given

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

perf-probe --del removes caches when --cache is given.
Note that the delete pattern is not same as normal events.

If you cached probes with event name, --del "eventname"
works as expected. However, if you skipped it, the cached
probes doesn't have actual event name. In that case
 --del "probe-desc" is required (wildcard is acceptable).
For example a cache entry has the probe-desc "vfs_read $params",
you can remove it with --del 'vfs_read*'.

  -
  # perf probe --cache --list
  /[kernel.kallsyms] (1466a0a250b5d0070c6d0f03c5fed30b237970a1):
  vfs_read $params
  /usr/lib64/libc-2.17.so (c31ffe7942bfd77b2fca8f9bd5709d387a86d3bc):
  getaddrinfo $params

  # perf probe --cache --del vfs_read\*
  Removed cached event: probe:vfs_read

  # perf probe --cache --list
  /[kernel.kallsyms] (1466a0a250b5d0070c6d0f03c5fed30b237970a1):
  /usr/lib64/libc-2.17.so (c31ffe7942bfd77b2fca8f9bd5709d387a86d3bc):
  getaddrinfo $params
  -

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v11:
  - Fix to check the result of purging cache entries.
  - Rename probe_cache__remove_entries to probe_cache__filter_purge.
 Changes in v9:
  - Fix to show which event is deleted (Thanks Hemant!)
 Changes in v4:
  - move del_perf_probe_caches() into builtin-probe.c since
command-line related delete procedure is there now.
---
 tools/perf/Documentation/perf-probe.txt |1 +
 tools/perf/builtin-probe.c  |   29 +
 tools/perf/util/probe-file.c|   36 ---
 tools/perf/util/probe-file.h|2 ++
 4 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index 5a70d45..8d09173 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -116,6 +116,7 @@ OPTIONS
(With --add) Cache the probes. Any events which successfully added
are also stored in the cache file.
(With --list) Show cached probes.
+   (With --del) Remove cached probes.
 
 --max-probes=NUM::
Set the maximum number of probe points for an event. Default is 128.
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 53e380c0e..6c2c0d1 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -363,6 +363,32 @@ out_cleanup:
return ret;
 }
 
+static int del_perf_probe_caches(struct strfilter *filter)
+{
+   struct probe_cache *cache;
+   struct strlist *bidlist;
+   struct str_node *nd;
+   int ret;
+
+   bidlist = build_id_cache__list_all();
+   if (!bidlist) {
+   ret = -errno;
+   pr_debug("Failed to get buildids: %d\n", ret);
+   return ret ?: -ENOMEM;
+   }
+
+   strlist__for_each(nd, bidlist) {
+   cache = probe_cache__new(nd->s);
+   if (!cache)
+   continue;
+   if (probe_cache__filter_purge(cache, filter) < 0 ||
+   probe_cache__commit(cache) < 0)
+   pr_warning("Failed to remove entries for %s\n", nd->s);
+   probe_cache__delete(cache);
+   }
+   return 0;
+}
+
 static int perf_del_probe_events(struct strfilter *filter)
 {
int ret, ret2, ufd = -1, kfd = -1;
@@ -375,6 +401,9 @@ static int perf_del_probe_events(struct strfilter *filter)
 
pr_debug("Delete filter: \'%s\'\n", str);
 
+   if (probe_conf.cache)
+   return del_perf_probe_caches(filter);
+
/* Get current event names */
ret = probe_file__open_both(, , PF_FL_RW);
if (ret < 0)
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 47e0e95..f8f710e 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -684,20 +684,40 @@ out:
return ret;
 }
 
+static bool probe_cache_entry__compare(struct probe_cache_entry *entry,
+  struct strfilter *filter)
+{
+   char buf[128], *ptr = entry->spev;
+
+   if (entry->pev.event) {
+   snprintf(buf, 128, "%s:%s", entry->pev.group, entry->pev.event);
+   ptr = buf;
+   }
+   return strfilter__compare(filter, ptr);
+}
+
+int probe_cache__filter_purge(struct probe_cache *pcache,
+ struct strfilter *filter)
+{
+   struct probe_cache_entry *entry, *tmp;
+
+   list_for_each_entry_safe(entry, tmp, >entries, node) {
+   if (probe_cache_entry__compare(entry, filter)) {
+   pr_info("Removed cached event: %s\n", entry->spev);
+   list_del_init(>node);
+   probe_cache_entry__delete(entry);
+   }
+   }
+   return 0;
+}
+
 static int probe_cache__show_entries(struct probe_cache *pcache,
 struct strfilter *filter)
 {

[PATCH perf/core v11 08/23] perf probe: Use cache entry if possible

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

Before analyzing debuginfo, try to find a corresponding entry
from probe cache always. This does not depend on --cache,
the --cache enables to store/update cache, but looking up
the cache is always enabled.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v6:
  - Remove fallback lookup routine by using function name
as cached event name, because it should be done by following
patch which supports %cached-event.
---
 tools/perf/util/probe-event.c |   65 -
 tools/perf/util/probe-file.c  |   20 -
 tools/perf/util/probe-file.h  |5 +++
 3 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 084756c..020c110 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2476,17 +2476,24 @@ static int probe_trace_event__set_name(struct 
probe_trace_event *tev,
char buf[64];
int ret;
 
+   /* If probe_event or trace_event already have the name, reuse it */
if (pev->event)
event = pev->event;
-   else
+   else if (tev->event)
+   event = tev->event;
+   else {
+   /* Or generate new one from probe point */
if (pev->point.function &&
(strncmp(pev->point.function, "0x", 2) != 0) &&
!strisglob(pev->point.function))
event = pev->point.function;
else
event = tev->point.realname;
+   }
if (pev->group)
group = pev->group;
+   else if (tev->group)
+   group = tev->group;
else
group = PERFPROBE_GROUP;
 
@@ -2533,7 +2540,7 @@ static int __add_probe_trace_events(struct 
perf_probe_event *pev,
for (i = 0; i < ntevs; i++) {
tev = [i];
/* Skip if the symbol is out of .text or blacklisted */
-   if (!tev->point.symbol)
+   if (!tev->point.symbol && !pev->uprobes)
continue;
 
/* Set new name for tev (and update namelist) */
@@ -2846,6 +2853,55 @@ errout:
 
 bool __weak arch__prefers_symtab(void) { return false; }
 
+static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
+ struct probe_trace_event **tevs)
+{
+   struct probe_cache *cache;
+   struct probe_cache_entry *entry;
+   struct probe_trace_event *tev;
+   struct str_node *node;
+   int ret, i;
+
+   cache = probe_cache__new(pev->target);
+   if (!cache)
+   return 0;
+
+   entry = probe_cache__find(cache, pev);
+   if (!entry) {
+   ret = 0;
+   goto out;
+   }
+
+   ret = strlist__nr_entries(entry->tevlist);
+   if (ret > probe_conf.max_probes) {
+   pr_debug("Too many entries matched in the cache of %s\n",
+pev->target ? : "kernel");
+   ret = -E2BIG;
+   goto out;
+   }
+
+   *tevs = zalloc(ret * sizeof(*tev));
+   if (!*tevs) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   i = 0;
+   strlist__for_each(node, entry->tevlist) {
+   tev = &(*tevs)[i++];
+   ret = parse_probe_trace_command(node->s, tev);
+   if (ret < 0)
+   goto out;
+   /* Set the uprobes attribute as same as original */
+   tev->uprobes = pev->uprobes;
+   }
+   ret = i;
+
+out:
+   probe_cache__delete(cache);
+   return ret;
+}
+
 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 struct probe_trace_event **tevs)
 {
@@ -2868,6 +2924,11 @@ static int convert_to_probe_trace_events(struct 
perf_probe_event *pev,
if (ret > 0)
return ret;
 
+   /* At first, we need to lookup cache entry */
+   ret = find_probe_trace_events_from_cache(pev, tevs);
+   if (ret > 0)
+   return ret; /* Found in probe cache */
+
if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
ret = find_probe_trace_events_from_map(pev, tevs);
if (ret > 0)
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 25a4042..58a60b3 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -524,7 +524,7 @@ static bool streql(const char *a, const char *b)
return !strcmp(a, b);
 }
 
-static struct probe_cache_entry *
+struct probe_cache_entry *
 probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
 {
struct probe_cache_entry *entry = NULL;
@@ -548,6 +548,24 @@ found:
return 

[PATCH perf/core v11 14/23] perf probe: Accept %sdt and %cached event name

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

To improbe usability, support %[PROVIDER:]SDTEVENT format to
add new probes on SDT and cached events.

e.g.
  
  # perf probe -x /lib/libc-2.17.so  %lll_lock_wait_private
  Added new event:
sdt_libc:lll_lock_wait_private (on %lll_lock_wait_private in
  /usr/lib/libc-2.17.so)

  You can now use it in all perf tools, such as:

  perf record -e sdt_libc:lll_lock_wait_private -aR sleep 1

  # perf probe -l | more
sdt_libc:lll_lock_wait_private (on __lll_lock_wait_private+21
   in /usr/lib/libc-2.17.so)
  

Note that this is not only for SDT events, but also normal
events with event-name.

e.g. define "myevent" on cache (-n doesn't add the real probe)
  
  # perf probe -x ./perf --cache -n --add 'myevent=dso__load $params'
  
  Reuse the "myevent" from cache as below.
  
  # perf probe -x ./perf %myevent
  

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v10:
  - Update Documentation/perf-probe.txt to add a link about SDT.
 Changes in v7:
  - Fix a bug to return an error if no SDT/cached events found in cache.
---
 tools/perf/Documentation/perf-probe.txt |9 +++
 tools/perf/util/probe-event.c   |   82 ++-
 tools/perf/util/probe-event.h   |1 
 tools/perf/util/probe-file.c|9 +++
 4 files changed, 76 insertions(+), 25 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index 7a258e9..39e3870 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -151,6 +151,8 @@ Probe points are defined by following syntax.
 3) Define event based on source file with lazy pattern
  [[GROUP:]EVENT=]SRC;PTN [ARG ...]
 
+4) Pre-defined SDT events or cached event with name
+ %[PROVIDER:]SDTEVENT
 
 'EVENT' specifies the name of new event, if omitted, it will be set the name 
of the probed function. You can also specify a group name by 'GROUP', if 
omitted, set 'probe' is used for kprobe and 'probe_' is used for uprobe.
 Note that using existing group name can conflict with other events. 
Especially, using the group name reserved for kernel modules can hide embedded 
events in the
@@ -158,6 +160,11 @@ modules.
 'FUNC' specifies a probed function name, and it may have one of the following 
options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is 
the relative-line number from function entry line, and '%return' means that it 
probes function return. And ';PTN' means lazy matching pattern (see LAZY 
MATCHING). Note that ';PTN' must be the end of the probe point definition.  In 
addition, '@SRC' specifies a source file which has that function.
 It is also possible to specify a probe point by the source line number or lazy 
matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file 
path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
 'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
+'SDTEVENT' and 'PROVIDER' is the pre-defined event name which is defined by 
user SDT (Statically Defined Tracing) or the pre-cached probes with event name.
+Note that before using the SDT event, the target binary (on which SDT events 
are defined) must be scanned by linkperf:perf-buildid-cache[1] to make SDT 
events as cached events.
+
+For details of the SDT, see below.
+https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
 
 PROBE ARGUMENT
 --
@@ -237,4 +244,4 @@ Add probes at malloc() function on libc
 
 SEE ALSO
 
-linkperf:perf-trace[1], linkperf:perf-record[1]
+linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1]
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index ed50f15..4aa2cf7 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1199,6 +1199,34 @@ err:
return err;
 }
 
+static int parse_perf_probe_event_name(char **arg, struct perf_probe_event 
*pev)
+{
+   char *ptr;
+
+   ptr = strchr(*arg, ':');
+   if (ptr) {
+   *ptr = '\0';
+   if (!is_c_func_name(*arg))
+   goto ng_name;
+   pev->group = strdup(*arg);
+   if (!pev->group)
+   return -ENOMEM;
+   *arg = ptr + 1;
+   } else
+   pev->group = NULL;
+   if (!is_c_func_name(*arg)) {
+ng_name:
+   semantic_error("%s is bad for event name -it must "
+  "follow C symbol-naming rule.\n", *arg);
+   return -EINVAL;
+   }
+   pev->event = strdup(*arg);
+   if (pev->event == NULL)
+   return -ENOMEM;
+
+   return 0;
+}
+
 /* Parse probepoint definition. */
 static int parse_perf_probe_point(char *arg, struct 

[PATCH perf/core v11 12/23] perf probe: Add group name support

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

Allow user to set group name for adding new event.
Note that user must ensure that the group name doesn't
conflict with existing group name carefully.
E.g. Existing group name can conflict with other events.
Especially, using the group name reserved for kernel
modules can hide kernel embedded events when loading
modules.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v4:
  - Update Documentation/perf-probe.txt too.
---
 tools/perf/Documentation/perf-probe.txt |   10 ++
 tools/perf/util/probe-event.c   |   23 ++-
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index 8d09173..7a258e9 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -143,16 +143,18 @@ PROBE SYNTAX
 Probe points are defined by following syntax.
 
 1) Define event based on function name
- [EVENT=]FUNC[@SRC][:RLN|+OFFS|%return|;PTN] [ARG ...]
+ [[GROUP:]EVENT=]FUNC[@SRC][:RLN|+OFFS|%return|;PTN] [ARG ...]
 
 2) Define event based on source file with line number
- [EVENT=]SRC:ALN [ARG ...]
+ [[GROUP:]EVENT=]SRC:ALN [ARG ...]
 
 3) Define event based on source file with lazy pattern
- [EVENT=]SRC;PTN [ARG ...]
+ [[GROUP:]EVENT=]SRC;PTN [ARG ...]
 
 
-'EVENT' specifies the name of new event, if omitted, it will be set the name 
of the probed function. Currently, event group name is set as 'probe'.
+'EVENT' specifies the name of new event, if omitted, it will be set the name 
of the probed function. You can also specify a group name by 'GROUP', if 
omitted, set 'probe' is used for kprobe and 'probe_' is used for uprobe.
+Note that using existing group name can conflict with other events. 
Especially, using the group name reserved for kernel modules can hide embedded 
events in the
+modules.
 'FUNC' specifies a probed function name, and it may have one of the following 
options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is 
the relative-line number from function entry line, and '%return' means that it 
probes function return. And ';PTN' means lazy matching pattern (see LAZY 
MATCHING). Note that ';PTN' must be the end of the probe point definition.  In 
addition, '@SRC' specifies a source file which has that function.
 It is also possible to specify a probe point by the source line number or lazy 
matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file 
path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
 'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index fbb101d..ed50f15 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1208,10 +1208,8 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
bool file_spec = false;
/*
 * 
-* perf probe [EVENT=]SRC[:LN|;PTN]
-* perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
-*
-* TODO:Group name support
+* perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
+* perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
 */
if (!arg)
return -EINVAL;
@@ -1220,11 +1218,19 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
if (ptr && *ptr == '=') {   /* Event name */
*ptr = '\0';
tmp = ptr + 1;
-   if (strchr(arg, ':')) {
-   semantic_error("Group name is not supported yet.\n");
-   return -ENOTSUP;
-   }
+   ptr = strchr(arg, ':');
+   if (ptr) {
+   *ptr = '\0';
+   if (!is_c_func_name(arg))
+   goto not_fname;
+   pev->group = strdup(arg);
+   if (!pev->group)
+   return -ENOMEM;
+   arg = ptr + 1;
+   } else
+   pev->group = NULL;
if (!is_c_func_name(arg)) {
+not_fname:
semantic_error("%s is bad for event name -it must "
   "follow C symbol-naming rule.\n", arg);
return -EINVAL;
@@ -1232,7 +1238,6 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
pev->event = strdup(arg);
if (pev->event == NULL)
return -ENOMEM;
-   pev->group = NULL;
arg = tmp;
}
 



[PATCH perf/core v11 08/23] perf probe: Use cache entry if possible

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

Before analyzing debuginfo, try to find a corresponding entry
from probe cache always. This does not depend on --cache,
the --cache enables to store/update cache, but looking up
the cache is always enabled.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v6:
  - Remove fallback lookup routine by using function name
as cached event name, because it should be done by following
patch which supports %cached-event.
---
 tools/perf/util/probe-event.c |   65 -
 tools/perf/util/probe-file.c  |   20 -
 tools/perf/util/probe-file.h  |5 +++
 3 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 084756c..020c110 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2476,17 +2476,24 @@ static int probe_trace_event__set_name(struct 
probe_trace_event *tev,
char buf[64];
int ret;
 
+   /* If probe_event or trace_event already have the name, reuse it */
if (pev->event)
event = pev->event;
-   else
+   else if (tev->event)
+   event = tev->event;
+   else {
+   /* Or generate new one from probe point */
if (pev->point.function &&
(strncmp(pev->point.function, "0x", 2) != 0) &&
!strisglob(pev->point.function))
event = pev->point.function;
else
event = tev->point.realname;
+   }
if (pev->group)
group = pev->group;
+   else if (tev->group)
+   group = tev->group;
else
group = PERFPROBE_GROUP;
 
@@ -2533,7 +2540,7 @@ static int __add_probe_trace_events(struct 
perf_probe_event *pev,
for (i = 0; i < ntevs; i++) {
tev = [i];
/* Skip if the symbol is out of .text or blacklisted */
-   if (!tev->point.symbol)
+   if (!tev->point.symbol && !pev->uprobes)
continue;
 
/* Set new name for tev (and update namelist) */
@@ -2846,6 +2853,55 @@ errout:
 
 bool __weak arch__prefers_symtab(void) { return false; }
 
+static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
+ struct probe_trace_event **tevs)
+{
+   struct probe_cache *cache;
+   struct probe_cache_entry *entry;
+   struct probe_trace_event *tev;
+   struct str_node *node;
+   int ret, i;
+
+   cache = probe_cache__new(pev->target);
+   if (!cache)
+   return 0;
+
+   entry = probe_cache__find(cache, pev);
+   if (!entry) {
+   ret = 0;
+   goto out;
+   }
+
+   ret = strlist__nr_entries(entry->tevlist);
+   if (ret > probe_conf.max_probes) {
+   pr_debug("Too many entries matched in the cache of %s\n",
+pev->target ? : "kernel");
+   ret = -E2BIG;
+   goto out;
+   }
+
+   *tevs = zalloc(ret * sizeof(*tev));
+   if (!*tevs) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   i = 0;
+   strlist__for_each(node, entry->tevlist) {
+   tev = &(*tevs)[i++];
+   ret = parse_probe_trace_command(node->s, tev);
+   if (ret < 0)
+   goto out;
+   /* Set the uprobes attribute as same as original */
+   tev->uprobes = pev->uprobes;
+   }
+   ret = i;
+
+out:
+   probe_cache__delete(cache);
+   return ret;
+}
+
 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 struct probe_trace_event **tevs)
 {
@@ -2868,6 +2924,11 @@ static int convert_to_probe_trace_events(struct 
perf_probe_event *pev,
if (ret > 0)
return ret;
 
+   /* At first, we need to lookup cache entry */
+   ret = find_probe_trace_events_from_cache(pev, tevs);
+   if (ret > 0)
+   return ret; /* Found in probe cache */
+
if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
ret = find_probe_trace_events_from_map(pev, tevs);
if (ret > 0)
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 25a4042..58a60b3 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -524,7 +524,7 @@ static bool streql(const char *a, const char *b)
return !strcmp(a, b);
 }
 
-static struct probe_cache_entry *
+struct probe_cache_entry *
 probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
 {
struct probe_cache_entry *entry = NULL;
@@ -548,6 +548,24 @@ found:
return entry;
 }
 
+struct probe_cache_entry *
+probe_cache__find_by_name(struct probe_cache 

[PATCH perf/core v11 14/23] perf probe: Accept %sdt and %cached event name

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

To improbe usability, support %[PROVIDER:]SDTEVENT format to
add new probes on SDT and cached events.

e.g.
  
  # perf probe -x /lib/libc-2.17.so  %lll_lock_wait_private
  Added new event:
sdt_libc:lll_lock_wait_private (on %lll_lock_wait_private in
  /usr/lib/libc-2.17.so)

  You can now use it in all perf tools, such as:

  perf record -e sdt_libc:lll_lock_wait_private -aR sleep 1

  # perf probe -l | more
sdt_libc:lll_lock_wait_private (on __lll_lock_wait_private+21
   in /usr/lib/libc-2.17.so)
  

Note that this is not only for SDT events, but also normal
events with event-name.

e.g. define "myevent" on cache (-n doesn't add the real probe)
  
  # perf probe -x ./perf --cache -n --add 'myevent=dso__load $params'
  
  Reuse the "myevent" from cache as below.
  
  # perf probe -x ./perf %myevent
  

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v10:
  - Update Documentation/perf-probe.txt to add a link about SDT.
 Changes in v7:
  - Fix a bug to return an error if no SDT/cached events found in cache.
---
 tools/perf/Documentation/perf-probe.txt |9 +++
 tools/perf/util/probe-event.c   |   82 ++-
 tools/perf/util/probe-event.h   |1 
 tools/perf/util/probe-file.c|9 +++
 4 files changed, 76 insertions(+), 25 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index 7a258e9..39e3870 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -151,6 +151,8 @@ Probe points are defined by following syntax.
 3) Define event based on source file with lazy pattern
  [[GROUP:]EVENT=]SRC;PTN [ARG ...]
 
+4) Pre-defined SDT events or cached event with name
+ %[PROVIDER:]SDTEVENT
 
 'EVENT' specifies the name of new event, if omitted, it will be set the name 
of the probed function. You can also specify a group name by 'GROUP', if 
omitted, set 'probe' is used for kprobe and 'probe_' is used for uprobe.
 Note that using existing group name can conflict with other events. 
Especially, using the group name reserved for kernel modules can hide embedded 
events in the
@@ -158,6 +160,11 @@ modules.
 'FUNC' specifies a probed function name, and it may have one of the following 
options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is 
the relative-line number from function entry line, and '%return' means that it 
probes function return. And ';PTN' means lazy matching pattern (see LAZY 
MATCHING). Note that ';PTN' must be the end of the probe point definition.  In 
addition, '@SRC' specifies a source file which has that function.
 It is also possible to specify a probe point by the source line number or lazy 
matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file 
path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
 'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
+'SDTEVENT' and 'PROVIDER' is the pre-defined event name which is defined by 
user SDT (Statically Defined Tracing) or the pre-cached probes with event name.
+Note that before using the SDT event, the target binary (on which SDT events 
are defined) must be scanned by linkperf:perf-buildid-cache[1] to make SDT 
events as cached events.
+
+For details of the SDT, see below.
+https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
 
 PROBE ARGUMENT
 --
@@ -237,4 +244,4 @@ Add probes at malloc() function on libc
 
 SEE ALSO
 
-linkperf:perf-trace[1], linkperf:perf-record[1]
+linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1]
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index ed50f15..4aa2cf7 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1199,6 +1199,34 @@ err:
return err;
 }
 
+static int parse_perf_probe_event_name(char **arg, struct perf_probe_event 
*pev)
+{
+   char *ptr;
+
+   ptr = strchr(*arg, ':');
+   if (ptr) {
+   *ptr = '\0';
+   if (!is_c_func_name(*arg))
+   goto ng_name;
+   pev->group = strdup(*arg);
+   if (!pev->group)
+   return -ENOMEM;
+   *arg = ptr + 1;
+   } else
+   pev->group = NULL;
+   if (!is_c_func_name(*arg)) {
+ng_name:
+   semantic_error("%s is bad for event name -it must "
+  "follow C symbol-naming rule.\n", *arg);
+   return -EINVAL;
+   }
+   pev->event = strdup(*arg);
+   if (pev->event == NULL)
+   return -ENOMEM;
+
+   return 0;
+}
+
 /* Parse probepoint definition. */
 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 {
@@ -1206,38 +1234,43 @@ static int parse_perf_probe_point(char *arg, 

[PATCH perf/core v11 12/23] perf probe: Add group name support

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

Allow user to set group name for adding new event.
Note that user must ensure that the group name doesn't
conflict with existing group name carefully.
E.g. Existing group name can conflict with other events.
Especially, using the group name reserved for kernel
modules can hide kernel embedded events when loading
modules.

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v4:
  - Update Documentation/perf-probe.txt too.
---
 tools/perf/Documentation/perf-probe.txt |   10 ++
 tools/perf/util/probe-event.c   |   23 ++-
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index 8d09173..7a258e9 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -143,16 +143,18 @@ PROBE SYNTAX
 Probe points are defined by following syntax.
 
 1) Define event based on function name
- [EVENT=]FUNC[@SRC][:RLN|+OFFS|%return|;PTN] [ARG ...]
+ [[GROUP:]EVENT=]FUNC[@SRC][:RLN|+OFFS|%return|;PTN] [ARG ...]
 
 2) Define event based on source file with line number
- [EVENT=]SRC:ALN [ARG ...]
+ [[GROUP:]EVENT=]SRC:ALN [ARG ...]
 
 3) Define event based on source file with lazy pattern
- [EVENT=]SRC;PTN [ARG ...]
+ [[GROUP:]EVENT=]SRC;PTN [ARG ...]
 
 
-'EVENT' specifies the name of new event, if omitted, it will be set the name 
of the probed function. Currently, event group name is set as 'probe'.
+'EVENT' specifies the name of new event, if omitted, it will be set the name 
of the probed function. You can also specify a group name by 'GROUP', if 
omitted, set 'probe' is used for kprobe and 'probe_' is used for uprobe.
+Note that using existing group name can conflict with other events. 
Especially, using the group name reserved for kernel modules can hide embedded 
events in the
+modules.
 'FUNC' specifies a probed function name, and it may have one of the following 
options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is 
the relative-line number from function entry line, and '%return' means that it 
probes function return. And ';PTN' means lazy matching pattern (see LAZY 
MATCHING). Note that ';PTN' must be the end of the probe point definition.  In 
addition, '@SRC' specifies a source file which has that function.
 It is also possible to specify a probe point by the source line number or lazy 
matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file 
path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
 'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index fbb101d..ed50f15 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1208,10 +1208,8 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
bool file_spec = false;
/*
 * 
-* perf probe [EVENT=]SRC[:LN|;PTN]
-* perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
-*
-* TODO:Group name support
+* perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
+* perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
 */
if (!arg)
return -EINVAL;
@@ -1220,11 +1218,19 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
if (ptr && *ptr == '=') {   /* Event name */
*ptr = '\0';
tmp = ptr + 1;
-   if (strchr(arg, ':')) {
-   semantic_error("Group name is not supported yet.\n");
-   return -ENOTSUP;
-   }
+   ptr = strchr(arg, ':');
+   if (ptr) {
+   *ptr = '\0';
+   if (!is_c_func_name(arg))
+   goto not_fname;
+   pev->group = strdup(arg);
+   if (!pev->group)
+   return -ENOMEM;
+   arg = ptr + 1;
+   } else
+   pev->group = NULL;
if (!is_c_func_name(arg)) {
+not_fname:
semantic_error("%s is bad for event name -it must "
   "follow C symbol-naming rule.\n", arg);
return -EINVAL;
@@ -1232,7 +1238,6 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
pev->event = strdup(arg);
if (pev->event == NULL)
return -ENOMEM;
-   pev->group = NULL;
arg = tmp;
}
 



  1   2   3   4   5   6   7   8   9   10   >