All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 07/14] range-diff: respect diff_option.file rather than assuming 'stdout'
From: Eric Sunshine @ 2018-07-23 23:20 UTC (permalink / raw)
  To: Stefan Beller
  Cc: Git List, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy,
	Ævar Arnfjörð Bjarmason
In-Reply-To: <CAGZ79kZ0OMrU_O5_rPdG7bNHRWQxVV1RguEg3g-pOa+kkgPCaA@mail.gmail.com>

On Mon, Jul 23, 2018 at 6:59 PM Stefan Beller <sbeller@google.com> wrote:
> On Sun, Jul 22, 2018 at 2:58 AM Eric Sunshine <sunshine@sunshineco.com> wrote:
> > The actual diffs output by range-diff respect diff_option.file, which
> > range-diff passes down the call-chain, thus are destination-agnostic.
> > However, output_pair_header() is hard-coded to emit to 'stdout'. Fix
> > this by making output_pair_header() respect diff_option.file, as well.
> >
> > Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
>
> Depending how much the range diff series has progressed
> already, it might make sense to squash it there?

It could be done that way, though it would be nice for Dscho's
range-diff series to land without another re-roll, and it looks like
I'll probably be re-rolling this series, anyhow, to move
show_interdiff() to diff-lib.c and to fix its signature. Junio could
manage it as a "squash", but that's probably more work for him than
for me to retain it in this series. *And*, this change _is_ required
for this series, whereas it doesn't really matter for Dscho's series,
even though it's an obvious "fix".

Anyhow, whichever way Junio and Dscho would like to play it is fine with me.

^ permalink raw reply

* Re: [PATCH v5] media: dvb-frontends: add Socionext MN88443x ISDB-S/T demodulator driver
From: kbuild test robot @ 2018-07-23 22:15 UTC (permalink / raw)
  To: Katsuhiro Suzuki
  Cc: kbuild-all, Mauro Carvalho Chehab, linux-media, Masami Hiramatsu,
	Jassi Brar, linux-arm-kernel, linux-kernel, Katsuhiro Suzuki
In-Reply-To: <20180723085150.24266-1-suzuki.katsuhiro@socionext.com>

[-- Attachment #1: Type: text/plain, Size: 1118 bytes --]

Hi Katsuhiro,

I love your patch! Yet something to improve:

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.18-rc6 next-20180723]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Katsuhiro-Suzuki/media-dvb-frontends-add-Socionext-MN88443x-ISDB-S-T-demodulator-driver/20180724-050011
base:   git://linuxtv.org/media_tree.git master
config: i386-randconfig-i1-201829 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

>> drivers/media/dvb-frontends/mn88443x.c:15:10: fatal error: sc1501a.h: No such file or directory
    #include "sc1501a.h"
             ^~~~~~~~~~~
   compilation terminated.

vim +15 drivers/media/dvb-frontends/mn88443x.c

    14	
  > 15	#include "sc1501a.h"
    16	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27693 bytes --]

^ permalink raw reply

* Re: [PATCH v4] iio: chemical: Add support for Bosch BME680 sensor
From: David Frey @ 2018-07-23 22:16 UTC (permalink / raw)
  To: Himanshu Jha, Daniel Baluta; +Cc: Linux Kernel Mailing List, linux-iio
In-Reply-To: <20180722222153.GA10066@himanshu-Vostro-3559>

On 7/22/2018 3:21 PM, Himanshu Jha wrote:
> On Sat, Jul 21, 2018 at 08:45:34PM +0300, Daniel Baluta wrote:
>> On Sat, Jul 21, 2018 at 6:43 PM, Andy Shevchenko
>> <andy.shevchenko@gmail.com> wrote:
>>> On Sat, Jul 21, 2018 at 6:36 PM, Himanshu Jha
>>> <himanshujha199640@gmail.com> wrote:
>>>
>>>>>> +   /* Look up table 1 for the possible gas range values */
>>>>>> +   u32 lookupTable1[16] = {2147483647u, 2147483647u, 2147483647u,
>>>>>> +                           2147483647u, 2147483647u, 2126008810u,
>>>>>> +                           2147483647u, 2130303777u, 2147483647u,
>>>>>> +                           2147483647u, 2143188679u, 2136746228u,
>>>>>> +                           2147483647u, 2126008810u, 2147483647u,
>>>>>> +                           2147483647u};
>>>
>>> This one needs perhaps a bit of though, but...
>>>
>>>>>> +   /* Look up table 2 for the possible gas range values */
>>>>>> +   u32 lookupTable2[16] = {4096000000u, 2048000000u, 1024000000u,
>>>>>> +                           512000000u, 255744255u, 127110228u, 64000000u,
>>>>>> +                           32258064u, 16016016u, 8000000u, 4000000u,
>>>>>> +                           2000000u, 1000000u, 500000u, 250000u, 125000u};
>>>
>>> ...this one obviously just a not needed one. You may replace it with a
>>> one constant and simple calculation to get either value (index from
>>> value, or value from index).
>>
>> Indeed this can be reduce to:
>>
>> 125.000 << (15 - idx).
>>
>> The real question here is if we approximate 255.744.255u to 256.00.00u how
>> much different is the result. Being a gas sensor I think it is very
>> hard to appreciate.
>>
>> We can go with this formula + adding a comment with the table with the
>> exact coefficients.
> 
> So, I have planned to use this 125000 << (15 - idx) equation with
> approximating the array members.
> 
> About the difference in results we would get after approximating isn't
> much of a problem IMHO because gas sensor is primarily used for IAQ, and
> IAQ is relative to the resistance reading.
> 
> For eg:
> 
> Resistance(ohm)			IAQ
> value < 30K			Very bad
> 30k < value < 50k		worse
> 50k < value < 70k		bad
> ...
> ..			
> so on..
> 
> So, what I simply imply is the scale will be adjusted and nothing else
> changes, unlike if it had been pressure, temperature, humidity.
> 
> The IAQ implementation is userspace application suggesting
> good/bad/ugly air quality.
> 
> And since we know David Frey is planning to use this sensor in his
> product mangOH board.
> 
> So, David, how are you planning to use the gas sensing part in your
> product ? RGB leds, buzzer, alarm ?
> 
> Thanks Andy for the suggestion :)
> 

My understanding is that the Bosch BSEC (Bosch Sensortec Environmental
Cluster - https://www.bosch-sensortec.com/bst/products/all_products/bsec)
software calculates the indoor air quality (IAQ) which is presented in
the range of 0 to 500.  BSEC is proprietary, pre-compiled static
library.  I don't know how they derive the IAQ, but it seems that it
could be based on smoothing outlying gas resistance values and 
integrating other values such as temperature, humidity and pressure.
Unless this driver can somehow produce IAQ values of equal or greater
reliability to the BSEC library, then I would prefer that it just
present the raw gas resistance value so that a user can write a program
to feed the sensor data into BSEC.

mangOH isn't really a traditional product.  It's an open hardware board
designed around Sierra Wireless cellular modules that run Linux.  So I
don't have any specific use case in mind, but I want to enable our users
(and thus future products) to make use of air quality measurements.

^ permalink raw reply

* `ohci_rh_resume()` called during `usb_dev_suspend()`
From: Paul Menzel @ 2018-07-23 23:19 UTC (permalink / raw)
  To: Alan Stern; +Cc: linux-usb, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2542 bytes --]

Dear Linux folks,


Profiling the suspend to and resume/wake-up from ACPI S3 with 
`sleepgraph.py` on an ASRock E350M1, I noticed that resume methods are 
called during suspend.

Here is an excerpt from the callgraph.

>   600.376906 |   0)   kworker-81   |               |  /* device_pm_callback_start: usb usb5, parent: 0000:00:14.5, type [suspend] */
>   600.376909 |   0)   kworker-81   |               |    usb_dev_suspend() {
>   600.376911 |   0)   kworker-81   |               |      usb_suspend() {
>   600.376913 |   0)   kworker-81   |               |        __pm_runtime_resume() {
>   600.376915 |   0)   kworker-81   |               |          _cond_resched() {
>   600.376917 |   0)   kworker-81   |   0.565 us    |            rcu_all_qs();
>   600.376921 |   0)   kworker-81   |   4.034 us    |          } /* _cond_resched */
>   600.376922 |   0)   kworker-81   |   0.505 us    |          _raw_spin_lock_irqsave();
>   600.376926 |   0)   kworker-81   |               |          rpm_resume() {
>   600.376928 |   0)   kworker-81   |   0.573 us    |            _raw_spin_lock();
>   600.376934 |   0)   kworker-81   |   0.706 us    |            rpm_resume();
>   600.376937 |   0)   kworker-81   |   0.556 us    |            _raw_spin_lock();
>   600.376942 |   0)   kworker-81   |   0.721 us    |            __rpm_get_callback();
>   600.376946 |   0)   kworker-81   |   0.564 us    |            dev_pm_disable_wake_irq_check();
>   600.376949 |   0)   kworker-81   |               |            rpm_callback() {
>   600.376952 |   0)   kworker-81   |               |              __rpm_callback() {
>   600.376954 |   0)   kworker-81   |               |                usb_runtime_resume() {
>   600.376956 |   0)   kworker-81   |               |                  usb_resume_both() {
>   600.376959 |   0)   kworker-81   |               |                    generic_resume() {
>   600.376960 |   0)   kworker-81   |               |                      hcd_bus_resume() {
>   600.376963 |   0)   kworker-81   |               |                        ohci_bus_resume [ohci_hcd]() {
>   600.376964 |   0)   kworker-81   |   0.588 us    |                          _raw_spin_lock_irq();
>   600.376968 |   0)   kworker-81   |               |                          ohci_rh_resume [ohci_hcd]() {
>   600.377043 |   0)   kworker-81   |               |                            msleep() {

Please find the full callgraph and the HTML output attached.

Is that expected?


Kind regards,

Paul


[1]: https://01.org/suspendresume

[-- Attachment #2: kodi_mem.html.7z --]
[-- Type: application/x-7z-compressed, Size: 41725 bytes --]

[-- Attachment #3: kodi_mem_ftrace-ohci.txt --]
[-- Type: text/plain, Size: 35634 bytes --]

  600.376906 |   0)   kworker-81   |               |  /* device_pm_callback_start: usb usb5, parent: 0000:00:14.5, type [suspend] */
  600.376909 |   0)   kworker-81   |               |    usb_dev_suspend() {
  600.376911 |   0)   kworker-81   |               |      usb_suspend() {
  600.376913 |   0)   kworker-81   |               |        __pm_runtime_resume() {
  600.376915 |   0)   kworker-81   |               |          _cond_resched() {
  600.376917 |   0)   kworker-81   |   0.565 us    |            rcu_all_qs();
  600.376921 |   0)   kworker-81   |   4.034 us    |          } /* _cond_resched */
  600.376922 |   0)   kworker-81   |   0.505 us    |          _raw_spin_lock_irqsave();
  600.376926 |   0)   kworker-81   |               |          rpm_resume() {
  600.376928 |   0)   kworker-81   |   0.573 us    |            _raw_spin_lock();
  600.376934 |   0)   kworker-81   |   0.706 us    |            rpm_resume();
  600.376937 |   0)   kworker-81   |   0.556 us    |            _raw_spin_lock();
  600.376942 |   0)   kworker-81   |   0.721 us    |            __rpm_get_callback();
  600.376946 |   0)   kworker-81   |   0.564 us    |            dev_pm_disable_wake_irq_check();
  600.376949 |   0)   kworker-81   |               |            rpm_callback() {
  600.376952 |   0)   kworker-81   |               |              __rpm_callback() {
  600.376954 |   0)   kworker-81   |               |                usb_runtime_resume() {
  600.376956 |   0)   kworker-81   |               |                  usb_resume_both() {
  600.376959 |   0)   kworker-81   |               |                    generic_resume() {
  600.376960 |   0)   kworker-81   |               |                      hcd_bus_resume() {
  600.376963 |   0)   kworker-81   |               |                        ohci_bus_resume [ohci_hcd]() {
  600.376964 |   0)   kworker-81   |   0.588 us    |                          _raw_spin_lock_irq();
  600.376968 |   0)   kworker-81   |               |                          ohci_rh_resume [ohci_hcd]() {
  600.377043 |   0)   kworker-81   |               |                            msleep() {
  600.377044 |   0)   kworker-81   |   0.591 us    |                              __msecs_to_jiffies();
  600.377048 |   0)   kworker-81   |               |                              schedule_timeout() {
 0)   kworker-81   =>  kworker-434  
 1)  sleepgr-779   =>   kworker-81  
  600.380611 |   1)   kworker-81   |   3561.688 us |                              } /* schedule_timeout */
  600.380613 |   1)   kworker-81   |   3569.619 us |                            } /* msleep */
  600.380625 |   1)   kworker-81   |               |                            msleep() {
  600.380626 |   1)   kworker-81   |   0.250 us    |                              __msecs_to_jiffies();
  600.380628 |   1)   kworker-81   |               |                              schedule_timeout() {
 1)   kworker-81   =>  kworker-434  
 0)  kworker-787   =>   kworker-81  
  600.386557 |   0)   kworker-81   |   5927.651 us |                              } /* schedule_timeout */
  600.386560 |   0)   kworker-81   |   5934.355 us |                            } /* msleep */
  600.386565 |   0)   kworker-81   |               |                            msleep() {
  600.386567 |   0)   kworker-81   |   0.490 us    |                              __msecs_to_jiffies();
  600.386570 |   0)   kworker-81   |               |                              schedule_timeout() {
 0)   kworker-81   =>  kworker-434  
 0)  kworker-434   =>   kworker-81  
  600.394208 |   0)   kworker-81   |   7636.340 us |                              } /* schedule_timeout */
  600.394211 |   0)   kworker-81   |   7644.604 us |                            } /* msleep */
  600.394212 |   0)   kworker-81   |   0.687 us    |                            _raw_spin_lock_irq();
  600.394217 |   0)   kworker-81   |   17247.00 us |                          } /* ohci_rh_resume [ohci_hcd] */
  600.394218 |   0)   kworker-81   |               |                          usb_hcd_poll_rh_status() {
  600.394220 |   0)   kworker-81   |               |                            ohci_hub_status_data [ohci_hcd]() {
  600.394221 |   0)   kworker-81   |   0.543 us    |                              _raw_spin_lock_irqsave();
  600.394301 |   0)   kworker-81   |   65.859 us   |                              _raw_spin_unlock_irqrestore();
  600.394371 |   0)   kworker-81   |   150.044 us  |                            } /* ohci_hub_status_data [ohci_hcd] */
  600.394373 |   0)   kworker-81   |   153.600 us  |                          } /* usb_hcd_poll_rh_status */
  600.394375 |   0)   kworker-81   |   17410.75 us |                        } /* ohci_bus_resume [ohci_hcd] */
  600.394376 |   0)   kworker-81   |   0.597 us    |                        _raw_spin_lock_irq();
  600.394380 |   0)   kworker-81   |               |                        usb_set_device_state() {
  600.394382 |   0)   kworker-81   |   0.499 us    |                          _raw_spin_lock_irqsave();
  600.394386 |   0)   kworker-81   |   0.532 us    |                          _raw_spin_unlock_irqrestore();
  600.394389 |   0)   kworker-81   |   7.880 us    |                        } /* usb_set_device_state */
  600.394391 |   0)   kworker-81   |   1.164 us    |                        usb_hub_find_child();
  600.394395 |   0)   kworker-81   |   0.621 us    |                        usb_hub_find_child();
  600.394399 |   0)   kworker-81   |   0.514 us    |                        usb_hub_find_child();
  600.394403 |   0)   kworker-81   |   17440.77 us |                      } /* hcd_bus_resume */
  600.394404 |   0)   kworker-81   |   17444.37 us |                    } /* generic_resume */
  600.394406 |   0)   kworker-81   |               |                    usb_resume_interface.isra.4() {
  600.394408 |   0)   kworker-81   |               |                      hub_resume() {
  600.394410 |   0)   kworker-81   |               |                        hub_activate() {
  600.394412 |   0)   kworker-81   |               |                          hub_ext_port_status() {
  600.394413 |   0)   kworker-81   |               |                            mutex_lock() {
  600.394415 |   0)   kworker-81   |   0.695 us    |                              _cond_resched();
  600.394419 |   0)   kworker-81   |   4.112 us    |                            } /* mutex_lock */
  600.394421 |   0)   kworker-81   |               |                            usb_control_msg() {
  600.394422 |   0)   kworker-81   |   22.651 us   |                              kmem_cache_alloc_trace();
  600.394449 |   0)   kworker-81   |   24.147 us   |                              usb_alloc_urb();
  600.394477 |   0)   kworker-81   |   486.801 us  |                              usb_start_wait_urb();
  600.394968 |   0)   kworker-81   |   3.343 us    |                              kfree();
  600.394975 |   0)   kworker-81   |   553.075 us  |                            } /* usb_control_msg */
  600.394977 |   0)   kworker-81   |   0.558 us    |                            mutex_unlock();
  600.394981 |   0)   kworker-81   |   567.881 us  |                          } /* hub_ext_port_status */
  600.394984 |   0)   kworker-81   |               |                          hub_ext_port_status() {
  600.394985 |   0)   kworker-81   |               |                            mutex_lock() {
  600.394987 |   0)   kworker-81   |   0.722 us    |                              _cond_resched();
  600.394991 |   0)   kworker-81   |   4.213 us    |                            } /* mutex_lock */
  600.394993 |   0)   kworker-81   |               |                            usb_control_msg() {
  600.394994 |   0)   kworker-81   |   21.092 us   |                              kmem_cache_alloc_trace();
  600.395019 |   0)   kworker-81   |   20.009 us   |                              usb_alloc_urb();
  600.395042 |   0)   kworker-81   |               |                              usb_start_wait_urb() {
 0)   kworker-81   =>  kworker-434  
 0)  kworker-787   =>   kworker-81  
  600.396526 |   0)   kworker-81   |   1481.933 us |                              } /* usb_start_wait_urb */
  600.396528 |   0)   kworker-81   |   3.372 us    |                              kfree();
  600.396534 |   0)   kworker-81   |   1540.251 us |                            } /* usb_control_msg */
  600.396536 |   0)   kworker-81   |   0.520 us    |                            mutex_unlock();
  600.396540 |   0)   kworker-81   |   1555.112 us |                          } /* hub_ext_port_status */
  600.396542 |   0)   kworker-81   |               |                          usb_submit_urb() {
  600.396545 |   0)   kworker-81   |   0.526 us    |                            usb_urb_ep_type_check();
  600.396549 |   0)   kworker-81   |               |                            usb_hcd_submit_urb() {
  600.396550 |   0)   kworker-81   |   0.510 us    |                              usb_get_urb();
  600.396554 |   0)   kworker-81   |   0.585 us    |                              _raw_spin_lock_irqsave();
  600.396558 |   0)   kworker-81   |   0.891 us    |                              usb_hcd_link_urb_to_ep();
  600.396562 |   0)   kworker-81   |   0.511 us    |                              _raw_spin_unlock_irqrestore();
  600.396566 |   0)   kworker-81   |   15.791 us   |                            } /* usb_hcd_submit_urb */
  600.396568 |   0)   kworker-81   |   23.948 us   |                          } /* usb_submit_urb */
  600.396571 |   0)   kworker-81   |               |                          kick_hub_wq.part.9() {
  600.396573 |   0)   kworker-81   |   0.701 us    |                            usb_autopm_get_interface_no_resume();
  600.396577 |   0)   kworker-81   |               |                            queue_work_on() {
  600.396579 |   0)   kworker-81   |   10.675 us   |                              __queue_work();
  600.396593 |   0)   kworker-81   |   14.645 us   |                            } /* queue_work_on */
  600.396595 |   0)   kworker-81   |   22.325 us   |                          } /* kick_hub_wq.part.9 */
  600.396597 |   0)   kworker-81   |   2185.388 us |                        } /* hub_activate */
  600.396599 |   0)   kworker-81   |   2189.006 us |                      } /* hub_resume */
  600.396600 |   0)   kworker-81   |   2192.768 us |                    } /* usb_resume_interface.isra.4 */
  600.396602 |   0)   kworker-81   |   19644.93 us |                  } /* usb_resume_both */
  600.396604 |   0)   kworker-81   |   19648.63 us |                } /* usb_runtime_resume */
  600.396606 |   0)   kworker-81   |   0.558 us    |                _raw_spin_lock_irq();
  600.396610 |   0)   kworker-81   |   19657.32 us |              } /* __rpm_callback */
  600.396612 |   0)   kworker-81   |   19661.36 us |            } /* rpm_callback */
  600.396615 |   0)   kworker-81   |               |            __wake_up() {
  600.396616 |   0)   kworker-81   |               |              __wake_up_common_lock() {
  600.396618 |   0)   kworker-81   |   0.514 us    |                _raw_spin_lock_irqsave();
  600.396621 |   0)   kworker-81   |   0.709 us    |                __wake_up_common();
  600.396625 |   0)   kworker-81   |   0.547 us    |                _raw_spin_unlock_irqrestore();
  600.396629 |   0)   kworker-81   |   11.214 us   |              } /* __wake_up_common_lock */
  600.396631 |   0)   kworker-81   |   14.627 us   |            } /* __wake_up */
  600.396633 |   0)   kworker-81   |               |            rpm_idle() {
  600.396634 |   0)   kworker-81   |   0.801 us    |              rpm_check_suspend_allowed();
  600.396639 |   0)   kworker-81   |   4.396 us    |            } /* rpm_idle */
  600.396640 |   0)   kworker-81   |   0.661 us    |            __pm_runtime_idle();
  600.396644 |   0)   kworker-81   |   0.522 us    |            _raw_spin_lock_irq();
  600.396648 |   0)   kworker-81   |   19720.92 us |          } /* rpm_resume */
  600.396650 |   0)   kworker-81   |   0.579 us    |          _raw_spin_unlock_irqrestore();
  600.396654 |   0)   kworker-81   |   19739.29 us |        } /* __pm_runtime_resume */
  600.396656 |   0)   kworker-81   |               |        usb_suspend_both() {
  600.396658 |   0)   kworker-81   |               |          hub_suspend() {
  600.396661 |   0)   kworker-81   |               |            hub_quiesce() {
  600.396662 |   0)   kworker-81   |               |              usb_kill_urb() {
  600.396664 |   0)   kworker-81   |               |                _cond_resched() {
  600.396666 |   0)   kworker-81   |   0.540 us    |                  rcu_all_qs();
  600.396670 |   0)   kworker-81   |   4.762 us    |                } /* _cond_resched */
  600.396672 |   0)   kworker-81   |               |                usb_hcd_unlink_urb() {
  600.396674 |   0)   kworker-81   |   0.567 us    |                  _raw_spin_lock_irqsave();
  600.396678 |   0)   kworker-81   |               |                  usb_get_dev() {
  600.396680 |   0)   kworker-81   |   0.585 us    |                    get_device();
  600.396684 |   0)   kworker-81   |   4.349 us    |                  } /* usb_get_dev */
  600.396685 |   0)   kworker-81   |   0.617 us    |                  _raw_spin_unlock_irqrestore();
  600.396689 |   0)   kworker-81   |               |                  unlink1() {
  600.396691 |   0)   kworker-81   |   0.573 us    |                    _raw_spin_lock_irqsave();
  600.396695 |   0)   kworker-81   |               |                    usb_hcd_unlink_urb_from_ep() {
  600.396697 |   0)   kworker-81   |   0.490 us    |                      _raw_spin_lock();
  600.396701 |   0)   kworker-81   |   4.046 us    |                    } /* usb_hcd_unlink_urb_from_ep */
  600.396702 |   0)   kworker-81   |               |                    usb_hcd_giveback_urb() {
  600.396704 |   0)   kworker-81   |   0.478 us    |                      _raw_spin_lock();
  600.396708 |   0)   kworker-81   |               |                      __tasklet_hi_schedule() {
  600.396709 |   0)   kworker-81   |               |                        __tasklet_schedule_common() {
  600.396711 |   0)   kworker-81   |   0.489 us    |                          __raise_softirq_irqoff();
  600.396715 |   0)   kworker-81   |               |                          wakeup_softirqd() {
  600.396717 |   0)   kworker-81   |               |                            wake_up_process() {
  600.396718 |   0)   kworker-81   |   6.689 us    |                              try_to_wake_up();
  600.396728 |   0)   kworker-81   |   10.227 us   |                            } /* wake_up_process */
  600.396730 |   0)   kworker-81   |   13.870 us   |                          } /* wakeup_softirqd */
  600.396732 |   0)   kworker-81   |   21.150 us   |                        } /* __tasklet_schedule_common */
  600.396734 |   0)   kworker-81   |   24.620 us   |                      } /* __tasklet_hi_schedule */
  600.396735 |   0)   kworker-81   |   31.807 us   |                    } /* usb_hcd_giveback_urb */
  600.396737 |   0)   kworker-81   |   0.558 us    |                    _raw_spin_unlock_irqrestore();
  600.396741 |   0)   kworker-81   |   50.480 us   |                  } /* unlink1 */
  600.396743 |   0)   kworker-81   |               |                  usb_put_dev() {
  600.396744 |   0)   kworker-81   |   0.620 us    |                    put_device();
  600.396748 |   0)   kworker-81   |   4.316 us    |                  } /* usb_put_dev */
  600.396750 |   0)   kworker-81   |   76.464 us   |                } /* usb_hcd_unlink_urb */
  600.396752 |   0)   kworker-81   |               |                _cond_resched() {
  600.396754 |   0)   kworker-81   |   0.493 us    |                  rcu_all_qs();
  600.396757 |   0)   kworker-81   |   3.960 us    |                } /* _cond_resched */
  600.396759 |   0)   kworker-81   |   0.561 us    |                init_wait_entry();
  600.396763 |   0)   kworker-81   |               |                prepare_to_wait_event() {
  600.396764 |   0)   kworker-81   |   0.733 us    |                  _raw_spin_lock_irqsave();
  600.396768 |   0)   kworker-81   |   0.582 us    |                  _raw_spin_unlock_irqrestore();
  600.396772 |   0)   kworker-81   |   7.802 us    |                } /* prepare_to_wait_event */
  600.396774 |   0)   kworker-81   |               |                schedule() {
  600.396776 |   0)   kworker-81   |               |                  rcu_note_context_switch() {
  600.396777 |   0)   kworker-81   |   0.495 us    |                    rcu_sched_qs();
  600.396781 |   0)   kworker-81   |   4.024 us    |                  } /* rcu_note_context_switch */
  600.396783 |   0)   kworker-81   |   0.493 us    |                  _raw_spin_lock();
  600.396786 |   0)   kworker-81   |   0.923 us    |                  update_rq_clock();
  600.396790 |   0)   kworker-81   |               |                  deactivate_task() {
  600.396793 |   0)   kworker-81   |               |                    dequeue_task_fair() {
  600.396795 |   0)   kworker-81   |               |                      dequeue_entity() {
  600.396796 |   0)   kworker-81   |               |                        update_curr() {
  600.396798 |   0)   kworker-81   |   0.528 us    |                          update_min_vruntime();
  600.396802 |   0)   kworker-81   |   0.537 us    |                          cpuacct_charge();
  600.396805 |   0)   kworker-81   |   7.724 us    |                        } /* update_curr */
  600.396807 |   0)   kworker-81   |   0.600 us    |                        __update_load_avg_se.isra.21();
  600.396811 |   0)   kworker-81   |   0.591 us    |                        __update_load_avg_cfs_rq.isra.22();
  600.396815 |   0)   kworker-81   |   0.561 us    |                        clear_buddies();
  600.396818 |   0)   kworker-81   |   0.608 us    |                        account_entity_dequeue();
  600.396822 |   0)   kworker-81   |   0.531 us    |                        update_cfs_group();
  600.396825 |   0)   kworker-81   |   29.358 us   |                      } /* dequeue_entity */
  600.396827 |   0)   kworker-81   |   0.469 us    |                      hrtick_update();
  600.396832 |   0)   kworker-81   |   37.247 us   |                    } /* dequeue_task_fair */
  600.396834 |   0)   kworker-81   |   41.369 us   |                  } /* deactivate_task */
  600.396835 |   0)   kworker-81   |               |                  wq_worker_sleeping() {
  600.396837 |   0)   kworker-81   |   0.507 us    |                    kthread_data();
  600.396842 |   0)   kworker-81   |   4.026 us    |                  } /* wq_worker_sleeping */
  600.396844 |   0)   kworker-81   |               |                  pick_next_task_fair() {
  600.396846 |   0)   kworker-81   |   0.490 us    |                    check_cfs_rq_runtime();
  600.396849 |   0)   kworker-81   |               |                    pick_next_entity() {
  600.396851 |   0)   kworker-81   |   0.508 us    |                      clear_buddies();
  600.396855 |   0)   kworker-81   |   4.061 us    |                    } /* pick_next_entity */
  600.396857 |   0)   kworker-81   |               |                    put_prev_entity() {
  600.396859 |   0)   kworker-81   |   0.483 us    |                      check_cfs_rq_runtime();
  600.396863 |   0)   kworker-81   |   4.064 us    |                    } /* put_prev_entity */
  600.396864 |   0)   kworker-81   |               |                    set_next_entity() {
  600.396867 |   0)   kworker-81   |   0.606 us    |                      __update_load_avg_se.isra.21();
  600.396870 |   0)   kworker-81   |   0.556 us    |                      __update_load_avg_cfs_rq.isra.22();
  600.396874 |   0)   kworker-81   |   8.356 us    |                    } /* set_next_entity */
  600.396876 |   0)   kworker-81   |   30.584 us   |                  } /* pick_next_task_fair */
  600.396879 |   0)   kworker-81   |   0.501 us    |                  enter_lazy_tlb();
 0)   kworker-81   =>  kworker-434  
 0)  kworker-434   =>   kworker-81  
  600.397304 |   0)   kworker-81   |               |                  finish_task_switch() {
  600.397307 |   0)   kworker-81   |   ==========> |
  600.397307 |   0)   kworker-81   |               |                    smp_apic_timer_interrupt() {
  600.397309 |   0)   kworker-81   |               |                      irq_enter() {
  600.397310 |   0)   kworker-81   |               |                        rcu_irq_enter() {
  600.397312 |   0)   kworker-81   |   0.555 us    |                          rcu_nmi_enter();
  600.397316 |   0)   kworker-81   |   4.100 us    |                        } /* rcu_irq_enter */
  600.397318 |   0)   kworker-81   |   0.760 us    |                        irqtime_account_irq();
  600.397322 |   0)   kworker-81   |   11.439 us   |                      } /* irq_enter */
  600.397323 |   0)   kworker-81   |               |                      hrtimer_interrupt() {
  600.397325 |   0)   kworker-81   |   0.508 us    |                        _raw_spin_lock_irqsave();
  600.397329 |   0)   kworker-81   |   0.837 us    |                        ktime_get_update_offsets_now();
  600.397332 |   0)   kworker-81   |               |                        __hrtimer_run_queues() {
  600.397334 |   0)   kworker-81   |   0.516 us    |                          __next_base();
  600.397338 |   0)   kworker-81   |   0.867 us    |                          __remove_hrtimer();
  600.397341 |   0)   kworker-81   |   0.540 us    |                          _raw_spin_unlock_irqrestore();
  600.397345 |   0)   kworker-81   |               |                          tick_sched_timer() {
  600.397347 |   0)   kworker-81   |   0.688 us    |                            ktime_get();
  600.397351 |   0)   kworker-81   |               |                            tick_sched_do_timer() {
  600.397352 |   0)   kworker-81   |   5.011 us    |                              tick_do_update_jiffies64.part.5();
  600.397361 |   0)   kworker-81   |   8.903 us    |                            } /* tick_sched_do_timer */
  600.397363 |   0)   kworker-81   |               |                            tick_sched_handle() {
  600.397364 |   0)   kworker-81   |   9.874 us    |                              update_process_times();
  600.397377 |   0)   kworker-81   |   0.537 us    |                              profile_tick();
  600.397381 |   0)   kworker-81   |   17.055 us   |                            } /* tick_sched_handle */
  600.397383 |   0)   kworker-81   |   0.605 us    |                            hrtimer_forward();
  600.397386 |   0)   kworker-81   |   39.630 us   |                          } /* tick_sched_timer */
  600.397388 |   0)   kworker-81   |   0.529 us    |                          _raw_spin_lock_irq();
  600.397391 |   0)   kworker-81   |   0.917 us    |                          enqueue_hrtimer();
  600.397395 |   0)   kworker-81   |   0.529 us    |                          __next_base();
  600.397399 |   0)   kworker-81   |   0.517 us    |                          __next_base();
  600.397402 |   0)   kworker-81   |   0.531 us    |                          __next_base();
  600.397406 |   0)   kworker-81   |   72.143 us   |                        } /* __hrtimer_run_queues */
  600.397407 |   0)   kworker-81   |               |                        __hrtimer_get_next_event() {
  600.397409 |   0)   kworker-81   |               |                          __hrtimer_next_event_base() {
  600.397411 |   0)   kworker-81   |   0.522 us    |                            __next_base();
  600.397414 |   0)   kworker-81   |   3.678 us    |                          } /* __hrtimer_next_event_base */
  600.397416 |   0)   kworker-81   |               |                          __hrtimer_next_event_base() {
  600.397417 |   0)   kworker-81   |   0.505 us    |                            __next_base();
  600.397420 |   0)   kworker-81   |   0.504 us    |                            __next_base();
  600.397424 |   0)   kworker-81   |   0.505 us    |                            __next_base();
  600.397427 |   0)   kworker-81   |   0.510 us    |                            __next_base();
  600.397430 |   0)   kworker-81   |   13.422 us   |                          } /* __hrtimer_next_event_base */
  600.397432 |   0)   kworker-81   |   23.157 us   |                        } /* __hrtimer_get_next_event */
  600.397433 |   0)   kworker-81   |   0.525 us    |                        _raw_spin_unlock_irqrestore();
  600.397437 |   0)   kworker-81   |               |                        tick_program_event() {
  600.397438 |   0)   kworker-81   |               |                          clockevents_program_event() {
  600.397440 |   0)   kworker-81   |   0.680 us    |                            ktime_get();
  600.397444 |   0)   kworker-81   |   0.695 us    |                            lapic_next_event();
  600.397448 |   0)   kworker-81   |   7.802 us    |                          } /* clockevents_program_event */
  600.397449 |   0)   kworker-81   |   11.130 us   |                        } /* tick_program_event */
  600.397451 |   0)   kworker-81   |   125.887 us  |                      } /* hrtimer_interrupt */
  600.397452 |   0)   kworker-81   |               |                      irq_exit() {
  600.397454 |   0)   kworker-81   |   0.804 us    |                        irqtime_account_irq();
  600.397458 |   0)   kworker-81   |               |                        do_softirq_own_stack() {
  600.397460 |   0)   kworker-81   |               |                          call_on_stack() {
  600.397462 |   0)   kworker-81   |               |                            __do_softirq() {
  600.397464 |   0)   kworker-81   |   0.766 us    |                              irqtime_account_irq();
  600.397467 |   0)   kworker-81   |   1.262 us    |                              run_timer_softirq();
  600.397472 |   0)   kworker-81   |   0.484 us    |                              rcu_bh_qs();
  600.397475 |   0)   kworker-81   |   0.855 us    |                              irqtime_account_irq();
  600.397479 |   0)   kworker-81   |   15.082 us   |                            } /* __do_softirq */
  600.397480 |   0)   kworker-81   |   18.533 us   |                          } /* call_on_stack */
  600.397482 |   0)   kworker-81   |   23.118 us   |                        } /* do_softirq_own_stack */
  600.397484 |   0)   kworker-81   |   0.502 us    |                        idle_cpu();
  600.397487 |   0)   kworker-81   |               |                        rcu_irq_exit() {
  600.397489 |   0)   kworker-81   |   0.528 us    |                          rcu_nmi_exit();
  600.397492 |   0)   kworker-81   |   3.782 us    |                        } /* rcu_irq_exit */
  600.397494 |   0)   kworker-81   |   40.070 us   |                      } /* irq_exit */
  600.397496 |   0)   kworker-81   |   187.073 us  |                    } /* smp_apic_timer_interrupt */
  600.397496 |   0)   kworker-81   |   <========== |
  600.397498 |   0)   kworker-81   |   192.165 us  |                  } /* finish_task_switch */
  600.397500 |   0)   kworker-81   |   724.625 us  |                } /* schedule */
  600.397501 |   0)   kworker-81   |               |                prepare_to_wait_event() {
  600.397503 |   0)   kworker-81   |   0.534 us    |                  _raw_spin_lock_irqsave();
  600.397506 |   0)   kworker-81   |   0.544 us    |                  _raw_spin_unlock_irqrestore();
  600.397510 |   0)   kworker-81   |   7.472 us    |                } /* prepare_to_wait_event */
  600.397512 |   0)   kworker-81   |               |                finish_wait() {
  600.397513 |   0)   kworker-81   |   0.505 us    |                  _raw_spin_lock_irqsave();
  600.397517 |   0)   kworker-81   |   0.522 us    |                  _raw_spin_unlock_irqrestore();
  600.397520 |   0)   kworker-81   |   7.139 us    |                } /* finish_wait */
  600.397522 |   0)   kworker-81   |   857.975 us  |              } /* usb_kill_urb */
  600.397524 |   0)   kworker-81   |   861.707 us  |            } /* hub_quiesce */
  600.397526 |   0)   kworker-81   |   865.786 us  |          } /* hub_suspend */
  600.397528 |   0)   kworker-81   |               |          generic_suspend() {
  600.397529 |   0)   kworker-81   |               |            hcd_bus_suspend() {
  600.397531 |   0)   kworker-81   |               |              ohci_bus_suspend [ohci_hcd]() {
  600.397533 |   0)   kworker-81   |   0.617 us    |                _raw_spin_lock_irq();
  600.397537 |   0)   kworker-81   |               |                ohci_rh_suspend [ohci_hcd]() {
  600.397540 |   0)   kworker-81   |   0.985 us    |                  update_done_list [ohci_hcd]();
  600.397544 |   0)   kworker-81   |   0.959 us    |                  ohci_work.part.13 [ohci_hcd]();
  600.397554 |   0)   kworker-81   |   15.217 us   |                } /* ohci_rh_suspend [ohci_hcd] */
  600.397555 |   0)   kworker-81   |               |                del_timer_sync() {
  600.397557 |   0)   kworker-81   |               |                  try_to_del_timer_sync() {
  600.397559 |   0)   kworker-81   |               |                    lock_timer_base() {
  600.397560 |   0)   kworker-81   |   0.563 us    |                      _raw_spin_lock_irqsave();
  600.397564 |   0)   kworker-81   |   3.844 us    |                    } /* lock_timer_base */
  600.397565 |   0)   kworker-81   |   0.546 us    |                    detach_if_pending();
  600.397568 |   0)   kworker-81   |   0.499 us    |                    _raw_spin_unlock_irqrestore();
  600.397572 |   0)   kworker-81   |   13.834 us   |                  } /* try_to_del_timer_sync */
  600.397574 |   0)   kworker-81   |   17.070 us   |                } /* del_timer_sync */
  600.397576 |   0)   kworker-81   |   42.649 us   |              } /* ohci_bus_suspend [ohci_hcd] */
  600.397577 |   0)   kworker-81   |               |              usb_set_device_state() {
  600.397579 |   0)   kworker-81   |   0.490 us    |                _raw_spin_lock_irqsave();
  600.397582 |   0)   kworker-81   |   0.576 us    |                _raw_spin_unlock_irqrestore();
  600.397586 |   0)   kworker-81   |   7.235 us    |              } /* usb_set_device_state */
  600.397588 |   0)   kworker-81   |               |              usb_phy_roothub_suspend() {
  600.397589 |   0)   kworker-81   |   0.478 us    |                usb_phy_roothub_power_off();
  600.397593 |   0)   kworker-81   |   3.791 us    |              } /* usb_phy_roothub_suspend */
  600.397595 |   0)   kworker-81   |   63.831 us   |            } /* hcd_bus_suspend */
  600.397596 |   0)   kworker-81   |   67.338 us   |          } /* generic_suspend */
  600.397598 |   0)   kworker-81   |               |          usb_hcd_flush_endpoint() {
  600.397600 |   0)   kworker-81   |               |            _cond_resched() {
  600.397601 |   0)   kworker-81   |   0.487 us    |              rcu_all_qs();
  600.397605 |   0)   kworker-81   |   3.954 us    |            } /* _cond_resched */
  600.397607 |   0)   kworker-81   |   0.653 us    |            _raw_spin_lock_irq();
  600.397611 |   0)   kworker-81   |   11.733 us   |          } /* usb_hcd_flush_endpoint */
  600.397613 |   0)   kworker-81   |               |          usb_hcd_flush_endpoint() {
  600.397614 |   0)   kworker-81   |               |            _cond_resched() {
  600.397616 |   0)   kworker-81   |   0.492 us    |              rcu_all_qs();
  600.397619 |   0)   kworker-81   |   3.690 us    |            } /* _cond_resched */
  600.397621 |   0)   kworker-81   |   0.499 us    |            _raw_spin_lock_irq();
  600.397624 |   0)   kworker-81   |   10.322 us   |          } /* usb_hcd_flush_endpoint */
  600.397626 |   0)   kworker-81   |   0.555 us    |          usb_hcd_flush_endpoint();
  600.397629 |   0)   kworker-81   |               |          usb_hcd_flush_endpoint() {
  600.397631 |   0)   kworker-81   |               |            _cond_resched() {
  600.397632 |   0)   kworker-81   |   0.496 us    |              rcu_all_qs();
  600.397636 |   0)   kworker-81   |   3.955 us    |            } /* _cond_resched */
  600.397637 |   0)   kworker-81   |   0.520 us    |            _raw_spin_lock_irq();
  600.397641 |   0)   kworker-81   |   10.904 us   |          } /* usb_hcd_flush_endpoint */
  600.397643 |   0)   kworker-81   |   0.520 us    |          usb_hcd_flush_endpoint();
  600.397646 |   0)   kworker-81   |   0.510 us    |          usb_hcd_flush_endpoint();
  600.397649 |   0)   kworker-81   |   0.513 us    |          usb_hcd_flush_endpoint();
  600.397652 |   0)   kworker-81   |   0.514 us    |          usb_hcd_flush_endpoint();
  600.397655 |   0)   kworker-81   |   0.520 us    |          usb_hcd_flush_endpoint();
  600.397659 |   0)   kworker-81   |   0.513 us    |          usb_hcd_flush_endpoint();
  600.397662 |   0)   kworker-81   |   0.519 us    |          usb_hcd_flush_endpoint();
  600.397665 |   0)   kworker-81   |   0.535 us    |          usb_hcd_flush_endpoint();
  600.397668 |   0)   kworker-81   |   0.505 us    |          usb_hcd_flush_endpoint();
  600.397672 |   0)   kworker-81   |   0.514 us    |          usb_hcd_flush_endpoint();
  600.397675 |   0)   kworker-81   |   0.511 us    |          usb_hcd_flush_endpoint();
  600.397678 |   0)   kworker-81   |   0.514 us    |          usb_hcd_flush_endpoint();
  600.397682 |   0)   kworker-81   |   0.511 us    |          usb_hcd_flush_endpoint();
  600.397685 |   0)   kworker-81   |   0.514 us    |          usb_hcd_flush_endpoint();
  600.397688 |   0)   kworker-81   |   0.511 us    |          usb_hcd_flush_endpoint();
  600.397691 |   0)   kworker-81   |   0.514 us    |          usb_hcd_flush_endpoint();
  600.397694 |   0)   kworker-81   |   0.510 us    |          usb_hcd_flush_endpoint();
  600.397699 |   0)   kworker-81   |   0.514 us    |          usb_hcd_flush_endpoint();
  600.397702 |   0)   kworker-81   |   0.517 us    |          usb_hcd_flush_endpoint();
  600.397706 |   0)   kworker-81   |   0.490 us    |          usb_hcd_flush_endpoint();
  600.397710 |   0)   kworker-81   |   0.511 us    |          usb_hcd_flush_endpoint();
  600.397713 |   0)   kworker-81   |   0.513 us    |          usb_hcd_flush_endpoint();
  600.397716 |   0)   kworker-81   |   0.546 us    |          usb_hcd_flush_endpoint();
  600.397719 |   0)   kworker-81   |   0.510 us    |          usb_hcd_flush_endpoint();
  600.397722 |   0)   kworker-81   |   0.543 us    |          usb_hcd_flush_endpoint();
  600.397726 |   0)   kworker-81   |   0.510 us    |          usb_hcd_flush_endpoint();
  600.397729 |   0)   kworker-81   |   0.536 us    |          usb_hcd_flush_endpoint();
  600.397732 |   0)   kworker-81   |   0.494 us    |          usb_hcd_flush_endpoint();
  600.397736 |   0)   kworker-81   |   1078.699 us |        } /* usb_suspend_both */
  600.397738 |   0)   kworker-81   |   20825.76 us |      } /* usb_suspend */
  600.397740 |   0)   kworker-81   |   20829.27 us |    } /* usb_dev_suspend */
  600.397742 |   0)   kworker-81   |   0.543 us    |    dev_driver_string();
  600.397746 |   0)   kworker-81   |   0.514 us    |    dev_driver_string();
  600.397749 |   0)   kworker-81   |               |  /* device_pm_callback_end: usb usb5, err=0 */

^ permalink raw reply

* Re: [PATCHv3 2/2] mtd: m25p80: restore the status of SPI flash when exiting
From: Boris Brezillon @ 2018-07-23 23:18 UTC (permalink / raw)
  To: Brian Norris
  Cc: Zhiqiang Hou, linux-mtd, Linux Kernel, David Woodhouse,
	Boris BREZILLON, Marek Vasut, Richard Weinberger, Cyrille Pitchen,
	NeilBrown
In-Reply-To: <CAN8TOE904WXMScHo1b2jhusz-L8eGBK=gzUUX079ZVfiFk+HoQ@mail.gmail.com>

+Neil

On Mon, 23 Jul 2018 15:06:43 -0700
Brian Norris <computersforpeace@gmail.com> wrote:

> Hi Boris,
> 
> On Mon, Jul 23, 2018 at 1:10 PM, Boris Brezillon
> <boris.brezillon@bootlin.com> wrote:
> > On Mon, 23 Jul 2018 11:13:50 -0700
> > Brian Norris <computersforpeace@gmail.com> wrote:  
> >> I noticed this got merged, but I wanted to put my 2 cents in here:  
> >
> > I wish you had replied to this thread when it was posted (more than
> > 6 months ago). Reverting the patch now implies making some people
> > unhappy because they'll have to resort to their old out-of-tree
> > hacks :-(.  
> 
> I'd say I'm sorry for not following things closely these days, but I'm
> not really that sorry. There are plenty of other capable hands. And if
> y'all shoot yourselves in the foot, so be it. This patch isn't going
> to blow things up, but now that I did finally notice it (because it
> happened to show up in a list of backports I was looking at), I
> thought better late than never to remind you.
> 
> For way of notification: Marek already noticed that we've started down
> a slippery slope months ago:
> 
> https://lkml.org/lkml/2018/4/8/141
> Re: [PATCH] mtd: spi-nor: clear Extended Address Reg on switch to
> 3-byte addressing.
> 
> I'm not quite sure why that wasn't taken to its logical conclusion --
> that the hack should be reverted.
> 
> This problem has been noted many times already, and we've always
> stayed on the side of *avoiding* this hack. A few references from a
> search of my email:
> 
> http://lists.infradead.org/pipermail/linux-mtd/2013-March/046343.html
> [PATCH 1/3] mtd: m25p80: utilize dedicated 4-byte addressing commands
> 
> http://lists.infradead.org/pipermail/barebox/2014-September/020682.html
> [RFC] MTD m25p80 3-byte addressing and boot problem
> 
> http://lists.infradead.org/pipermail/linux-mtd/2015-February/057683.html
> [PATCH 2/2] m25p80: if supported put chip to deep power down if not used

To my defense, I was not actively following SPI NOR topics at this
time, but, in the light of those discussions, I still keep thinking we
should try our best to improve support for broken HW.
So, ideally, we should find a way to support getting back to 3-byte
addressing mode when resetting, while generating enough noise to make
people well aware that their board design is broken (I think the
proposal of the new DT prop + a WARN_ON() is a good idea).

> 
> >> On Wed, Dec 06, 2017 at 10:53:42AM +0800, Zhiqiang Hou wrote:  
> >> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >> >
> >> > Restore the status to be compatible with legacy devices.
> >> > Take Freescale eSPI boot for example, it copies (in 3 Byte
> >> > addressing mode) the RCW and bootloader images from SPI flash
> >> > without firing a reset signal previously, so the reboot command
> >> > will fail without reseting the addressing mode of SPI flash.
> >> > This patch implement .shutdown function to restore the status
> >> > in reboot process, and add the same operation to the .remove
> >> > function.  
> >>
> >> We have previously rejected this patch multiple times, because the above
> >> comment demonstrates a broken product.  
> >
> > If we were to only support working HW parts, I fear Linux would not
> > support a lot of HW (that's even more true when it comes to flashes :P).  
> 
> You stopped allowing UBI to attach to MLC NAND recently, no? That
> sounds like almost the same boat -- you've probably killed quite a few
> shitty products, if they were to use mainline directly.

Well, that's a bit different in that it's purely a SW issue, and we
also try to encourage people to take over the work we started with
Richard to fix that problem. But I get your point, we broke setups that
were working in an unreliable way, pretty much what you're suggesting to
do here.

> 
> Anyway, that's derailing the issue. Supporting broken hardware isn't
> something you try to do by applying the same hack to all systems. You
> normally try to apply your hack as narrowly as possible.

This, I agree with.

> You seem to
> imply that below. So maybe that's a solution to move forward with. But
> I'd personally be just as happy to see the patch reverted.
> 
> >> You cannot guarantee that all
> >> reboots will invoke the .shutdown() method -- what about crashes? What
> >> about watchdog resets? IIUC, those will hit the same broken behavior,
> >> and have unexepcted behavior in your bootloader.  
> >
> > Yes, there are corner cases that are not addressed with this approach,  
> 
> Is a system crash really a corner case? :D

Well, nothing forces you to reset the platform using a HW reset when
that happens :P.

> 
> > but it still seems to improve things. Of course, that means the
> > user should try to re-route all HW reset sources to SW ones (RESET input
> > pin muxed to the GPIO controller, watchdog generating an interrupt
> > instead of directly asserting the RESET output pin), which is not always
> > possible, but even when it's not, isn't it better to have a setup that
> > works fine 99% of the time instead of 50% of the time?  
> 
> Perhaps, but not at the expense of future development. And
> realistically, no one is doing that if they have this hack. Most
> people won't even know that this hack is protecting them at all (so
> again, they won't try to mitigate the problem any further).

Unless we add a huge backtrace at probe time which forces them to look
closer at what they did wrong (like you seem to suggest below).

> 
> >> I suppose one could argue for doing this in remove(), but AIUI you're
> >> just papering over system bugs by introducing the shutdown() function
> >> here. Thus, I'd prefer we drop the shutdown() method to avoid misleading
> >> other users of this driver.  
> >
> > I understand your point. But if the problem is about making sure people
> > designing new boards get that right, why not complaining at probe time
> > when things are wrong?
> >
> > I mean, spi_nor_restore() seems to only do something on very specific
> > NORs (those on which a SW RESET does not resets the addressing
> > mode).  
> 
> The point isn't that SW RESET doesn't reset the addressing mode -- it
> does on any flash I've seen. The point is that most systems are built
> around a stateless assumption in these flash. IIRC, there wasn't even
> a SW RESET command at all until these "huge" flash came around and
> stateful addressing modes came about. So boot ROMs and bootloaders
> would have to be updated to start figuring out when/how to do this SW
> RESET. And once two vendors start doing it differently (I'm not sure:
> have they done this already? I think so) it's no longer something a
> boot ROM will get right.
> 
> The only way to get this stuff right is to have a hardware reset, or
> else to avoid all of the stateful modes in software.

Okay.

> 
> > So, how about adding a flag that says "my board has the NOR HW
> > RESET pin wired" (there would be a DT props to set that flag). Then you
> > add a WARN_ON() when this flag is not set and a NOR chip impacted by
> > this bug is detected.  
> 
> I'd kinda prefer the reverse. There really isn't a need to document
> anything for a working system (software usually can't control this
> RESET pin). The burden should be on the b0rked system to document
> where it needs unsound hacks to survive.

That's true.

> 
> > This way you make sure people are informed that
> > they're doing something wrong, and for those who can't change their HW
> > (because it's already widely deployed), you have a fix that improve
> > things.  
> 
> Or even better: put this hack behind a DT flag, so that one has to
> admit that their board design is broken before it will even do
> anything. Proposal: "linux,badly-designed-flash-reset".

I think we can remove the "linux," prefix. If it's badly designed, it
applies to all OSes, don't you think?

Regards,

Boris

^ permalink raw reply

* Re: [PATCH v5] PCI: Check for PCIe downtraining conditions
From: Jakub Kicinski @ 2018-07-23 22:14 UTC (permalink / raw)
  To: Tal Gilboa
  Cc: Alexandru Gagniuc, linux-pci@vger.kernel.org, bhelgaas@google.com,
	keith.busch@intel.com, alex_gagniuc@dellteam.com,
	austin_bolen@dell.com, shyam_iyer@dell.com,
	jeffrey.t.kirsher@intel.com, ariel.elior@cavium.com,
	michael.chan@broadcom.com, ganeshgr@chelsio.com, Tariq Toukan,
	airlied@gmail.com, alexander.deucher@amd.com,
	mike.marciniszyn@intel.com, linux-kernel@vger.kernel.org
In-Reply-To: <b9a6b3b8-56cf-8bb5-2568-071ccd8a4f28@mellanox.com>

On Tue, 24 Jul 2018 00:52:22 +0300, Tal Gilboa wrote:
> On 7/24/2018 12:01 AM, Jakub Kicinski wrote:
> > On Mon, 23 Jul 2018 15:03:38 -0500, Alexandru Gagniuc wrote:  
> >> PCIe downtraining happens when both the device and PCIe port are
> >> capable of a larger bus width or higher speed than negotiated.
> >> Downtraining might be indicative of other problems in the system, and
> >> identifying this from userspace is neither intuitive, nor
> >> straightforward.
> >>
> >> The easiest way to detect this is with pcie_print_link_status(),
> >> since the bottleneck is usually the link that is downtrained. It's not
> >> a perfect solution, but it works extremely well in most cases.
> >>
> >> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> >> ---
> >>
> >> For the sake of review, I've created a __pcie_print_link_status() which
> >> takes a 'verbose' argument. If we agree want to go this route, and update
> >> the users of pcie_print_link_status(), I can split this up in two patches.
> >> I prefer just printing this information in the core functions, and letting
> >> drivers not have to worry about this. Though there seems to be strong for
> >> not going that route, so here it goes:  
> > 
> > FWIW the networking drivers print PCIe BW because sometimes the network
> > bandwidth is simply over-provisioned on multi port cards, e.g. 80Gbps
> > card on a x8 link.
> > 
> > Sorry to bike shed, but currently the networking cards print the info
> > during probe.  Would it make sense to move your message closer to probe
> > time?  Rather than when device is added.  If driver structure is
> > available, we could also consider adding a boolean to struct pci_driver
> > to indicate if driver wants the verbose message?  This way we avoid
> > duplicated prints.
> > 
> > I have no objection to current patch, it LGTM.  Just a thought.  
> 
> I don't see the reason for having two functions. What's the problem with 
> adding the verbose argument to the original function?

IMHO it's reasonable to keep the default parameter to what 90% of users
want by a means on a wrapper.  The non-verbose output is provided by
the core already for all devices.

What do you think of my proposal above Tal?  That would make the extra
wrapper unnecessary since the verbose parameter would be part of the
driver structure, and it would avoid the duplicated output.

^ permalink raw reply

* Re: Linux 4.18-rc6
From: Linus Torvalds @ 2018-07-23 23:17 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: David Miller, Martin Schwidefsky, Linux Kernel Mailing List
In-Reply-To: <20180723212330.GA7441@roeck-us.net>

On Mon, Jul 23, 2018 at 2:23 PM Guenter Roeck <linux@roeck-us.net> wrote:
>
> >
> > Martin - can we just remove the
> >
> >          select HAVE_GCC_PLUGINS
> >
> > from the s390 Kconfig file (or perhaps add "if BROKEN" or something to
> > disable it).
> >
> > Because if it's not getting fixed, it shouldn't be exposed.
> >
> The problem only affects 4.18 - the code has been rearranged in -next.
> Only, in my builders, I can't disable a flag for individual releases,
> so I just disabled it completely for s390.

Well, I'm not going to release a 4.18 with a known problem, so in 4.18
this *will* be disabled if it's not fixed.

The fact that it might be fixed in linux-next is entirely immaterial
to the release of 4.18.

                   Linus

^ permalink raw reply

* Re: [PATCH v2] systemd: Allow custom coredump config options
From: Alistair Francis @ 2018-07-23 23:16 UTC (permalink / raw)
  To: Andre McCurdy; +Cc: OE Core mailing list
In-Reply-To: <CAJ86T=XuEUrsb8gZAXmh3m+sXFpU2T=bXqNRhjLYUNCH9DNtDg@mail.gmail.com>

On Wed, Jul 18, 2018 at 4:48 PM, Andre McCurdy <armccurdy@gmail.com> wrote:
> On Wed, Jul 18, 2018 at 3:53 PM, Alistair Francis
> <alistair.francis@wdc.com> wrote:
>> If the user has enabled coredump let's allow them to customise the
>> config options.
>>
>> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
>> ---
>>  meta/recipes-core/systemd/systemd_239.bb | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/meta/recipes-core/systemd/systemd_239.bb b/meta/recipes-core/systemd/systemd_239.bb
>> index 7822548993..a625d060a9 100644
>> --- a/meta/recipes-core/systemd/systemd_239.bb
>> +++ b/meta/recipes-core/systemd/systemd_239.bb
>> @@ -279,6 +279,18 @@ do_install() {
>>                         chown polkitd:root ${D}${datadir}/polkit-1/rules.d
>>                 fi
>>         fi
>> +
>> +  # If coredump was enabled, enable it in the config.
>> +  # This just sets the default, but can be used to customise the values.
>> +  if ${@bb.utils.contains('PACKAGECONFIG', 'coredump', 'true', 'false', d)}; then
>> +    sed 's|#Storage.*|Storage=external|g' -i ${D}${sysconfdir}/systemd/coredump.conf
>> +    sed 's|#Compress.*|Compress=yes|g' -i ${D}${sysconfdir}/systemd/coredump.conf
>> +    sed 's|#ProcessSizeMax.*|ProcessSizeMax=2G|g' -i ${D}${sysconfdir}/systemd/coredump.conf
>> +    sed 's|#ExternalSizeMax.*|ExternalSizeMax=2G|g' -i ${D}${sysconfdir}/systemd/coredump.conf
>> +    sed 's|#JournalSizeMax.*|JournalSizeMax=767M|g' -i ${D}${sysconfdir}/systemd/coredump.conf
>> +    sed 's|#MaxUse.*|MaxUse=|g' -i ${D}${sysconfdir}/systemd/coredump.conf
>> +    sed 's|#KeepFree.*|KeepFree=|g' -i ${D}${sysconfdir}/systemd/coredump.conf
>
> How does this allow the user to customise the config options?

They can edit the sed command line and have different options.

>
> By forcing the options to the _current_ default values you are
> creating a maintenance problem - ie you'll still be forcing these
> values even if/when the upstream defaults are changed.

That is a good point, is there a usual way to allow edits to config
files like this?

Alistair

>
>> +  fi
>>  }
>>
>>
>> --
>> 2.17.1
>>
>> --
>> _______________________________________________
>> Openembedded-core mailing list
>> Openembedded-core@lists.openembedded.org
>> http://lists.openembedded.org/mailman/listinfo/openembedded-core
> --
> _______________________________________________
> Openembedded-core mailing list
> Openembedded-core@lists.openembedded.org
> http://lists.openembedded.org/mailman/listinfo/openembedded-core


^ permalink raw reply

* Re: [PATCH v2] perf/core: fix a possible deadlock scenario
From: Cong Wang @ 2018-07-23 23:16 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: LKML, Ingo Molnar, Linus Torvalds, Arnaldo Carvalho de Melo,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, stable
In-Reply-To: <20180720115217.GQ2494@hirez.programming.kicks-ass.net>

On Fri, Jul 20, 2018 at 4:52 AM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Thu, Jul 19, 2018 at 12:12:53PM -0700, Cong Wang wrote:
> > hrtimer_cancel() busy-waits for the hrtimer callback to stop,
> > pretty much like del_timer_sync(). This creates a possible deadlock
> > scenario where we hold a spinlock before calling hrtimer_cancel()
> > while in trying to acquire the same spinlock in the callback.
>
> Has this actually been observed?


Without lockdep annotation, it is not easy to observe.


>
> > cpu_clock_event_init():
> >   perf_swevent_init_hrtimer():
> >     hwc->hrtimer.function = perf_swevent_hrtimer;
> >
> > perf_swevent_hrtimer():
> >   __perf_event_overflow():
> >     __perf_event_account_interrupt():
> >       perf_adjust_period():
> >         pmu->stop():
> >         cpu_clock_event_stop():
> >           perf_swevent_cancel():
> >             hrtimer_cancel()
>
> Please explain how a hrtimer event ever gets to perf_adjust_period().
> Last I checked perf_swevent_init_hrtimer() results in attr.freq=0.

Good point.

I thought attr.freq is specified by user-space, but seems
perf_swevent_init_hrtimer() clears it purposely and will not change
after initialization, interesting...


>
> > Getting stuck in an hrtimer is a disaster:
>
> You'll get NMI watchdog splats. Getting stuck in NMI context is far more
> 'interesting :-)

Yes, I did see a stack trace in perf_swevent_hrtimer() which led
me here. But I have to admit among those hundreds of soft lockup's,
I only saw one showing swevent hrtimer backtrace.

Previously I thought this is because of NMI handler race, but Jiri
pointed out the race doesn't exist.


>
> > +#define PERF_EF_NO_WAIT      0x08            /* do not wait when stopping, for
> > +                                      * example, waiting for a timer
> > +                                      */
>
> That's a broken comment style.

It is picked by checkpatch.pl, not me, I chose a different one and got
a complain. :)

Thanks!

^ permalink raw reply

* Re: Linux 4.18-rc6
From: Linus Torvalds @ 2018-07-23 23:16 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: David Miller, Martin Schwidefsky, Linux Kernel Mailing List
In-Reply-To: <20180723212330.GA7441@roeck-us.net>

On Mon, Jul 23, 2018 at 2:23 PM Guenter Roeck <linux@roeck-us.net> wrote:
>
> My patch is also at
>
> https://patchwork.ozlabs.org/patch/937283/

Ah, ok, so that just adds the forward-declaration of 'struct page' in
the right global namespace.

Anyway, I'll just re-order the includes as I suggested, which I think
is the right fix and makes the forward-declaration unnecessary
(although not _wrong_)

                 Linus

^ permalink raw reply

* [net-next V2 12/12] net/mlx5e: Use PARTIAL_GSO for UDP segmentation
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Boris Pismenny, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

From: Boris Pismenny <borisp@mellanox.com>

This patch removes the splitting of UDP_GSO_L4 packets in the driver,
and exposes UDP_GSO_L4 as a PARTIAL_GSO feature. Thus, the network stack
is not responsible for splitting the packet into two.

Signed-off-by: Boris Pismenny <borisp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../net/ethernet/mellanox/mlx5/core/Makefile  |   4 +-
 .../mellanox/mlx5/core/en_accel/en_accel.h    |  27 +++--
 .../mellanox/mlx5/core/en_accel/rxtx.c        | 109 ------------------
 .../mellanox/mlx5/core/en_accel/rxtx.h        |  14 ---
 .../net/ethernet/mellanox/mlx5/core/en_main.c |   9 +-
 5 files changed, 23 insertions(+), 140 deletions(-)
 delete mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_accel/rxtx.c
 delete mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_accel/rxtx.h

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index 55d5a5c2e9d8..fa7fcca5dc78 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -14,8 +14,8 @@ mlx5_core-$(CONFIG_MLX5_FPGA) += fpga/cmd.o fpga/core.o fpga/conn.o fpga/sdk.o \
 		fpga/ipsec.o fpga/tls.o
 
 mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \
-		en_tx.o en_rx.o en_dim.o en_txrx.o en_accel/rxtx.o en_stats.o  \
-		vxlan.o en_arfs.o en_fs_ethtool.o en_selftest.o en/port.o
+		en_tx.o en_rx.o en_dim.o en_txrx.o en_stats.o vxlan.o          \
+		en_arfs.o en_fs_ethtool.o en_selftest.o en/port.o
 
 mlx5_core-$(CONFIG_MLX5_MPFS) += lib/mpfs.o
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
index 39a5d13ba459..1dd225380a66 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
@@ -38,14 +38,22 @@
 #include <linux/netdevice.h>
 #include "en_accel/ipsec_rxtx.h"
 #include "en_accel/tls_rxtx.h"
-#include "en_accel/rxtx.h"
 #include "en.h"
 
-static inline struct sk_buff *mlx5e_accel_handle_tx(struct sk_buff *skb,
-						    struct mlx5e_txqsq *sq,
-						    struct net_device *dev,
-						    struct mlx5e_tx_wqe **wqe,
-						    u16 *pi)
+static inline void
+mlx5e_udp_gso_handle_tx_skb(struct sk_buff *skb)
+{
+	int payload_len = skb_shinfo(skb)->gso_size + sizeof(struct udphdr);
+
+	udp_hdr(skb)->len = htons(payload_len);
+}
+
+static inline struct sk_buff *
+mlx5e_accel_handle_tx(struct sk_buff *skb,
+		      struct mlx5e_txqsq *sq,
+		      struct net_device *dev,
+		      struct mlx5e_tx_wqe **wqe,
+		      u16 *pi)
 {
 #ifdef CONFIG_MLX5_EN_TLS
 	if (test_bit(MLX5E_SQ_STATE_TLS, &sq->state)) {
@@ -63,11 +71,8 @@ static inline struct sk_buff *mlx5e_accel_handle_tx(struct sk_buff *skb,
 	}
 #endif
 
-	if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) {
-		skb = mlx5e_udp_gso_handle_tx_skb(dev, sq, skb, wqe, pi);
-		if (unlikely(!skb))
-			return NULL;
-	}
+	if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4)
+		mlx5e_udp_gso_handle_tx_skb(skb);
 
 	return skb;
 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/rxtx.c
deleted file mode 100644
index 7b7ec3998e84..000000000000
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/rxtx.c
+++ /dev/null
@@ -1,109 +0,0 @@
-#include "en_accel/rxtx.h"
-
-static void mlx5e_udp_gso_prepare_last_skb(struct sk_buff *skb,
-					   struct sk_buff *nskb,
-					   int remaining)
-{
-	int bytes_needed = remaining, remaining_headlen, remaining_page_offset;
-	int headlen = skb_transport_offset(skb) + sizeof(struct udphdr);
-	int payload_len = remaining + sizeof(struct udphdr);
-	int k = 0, i, j;
-
-	skb_copy_bits(skb, 0, nskb->data, headlen);
-	nskb->dev = skb->dev;
-	skb_reset_mac_header(nskb);
-	skb_set_network_header(nskb, skb_network_offset(skb));
-	skb_set_transport_header(nskb, skb_transport_offset(skb));
-	skb_set_tail_pointer(nskb, headlen);
-
-	/* How many frags do we need? */
-	for (i = skb_shinfo(skb)->nr_frags - 1; i >= 0; i--) {
-		bytes_needed -= skb_frag_size(&skb_shinfo(skb)->frags[i]);
-		k++;
-		if (bytes_needed <= 0)
-			break;
-	}
-
-	/* Fill the first frag and split it if necessary */
-	j = skb_shinfo(skb)->nr_frags - k;
-	remaining_page_offset = -bytes_needed;
-	skb_fill_page_desc(nskb, 0,
-			   skb_shinfo(skb)->frags[j].page.p,
-			   skb_shinfo(skb)->frags[j].page_offset + remaining_page_offset,
-			   skb_shinfo(skb)->frags[j].size - remaining_page_offset);
-
-	skb_frag_ref(skb, j);
-
-	/* Fill the rest of the frags */
-	for (i = 1; i < k; i++) {
-		j = skb_shinfo(skb)->nr_frags - k + i;
-
-		skb_fill_page_desc(nskb, i,
-				   skb_shinfo(skb)->frags[j].page.p,
-				   skb_shinfo(skb)->frags[j].page_offset,
-				   skb_shinfo(skb)->frags[j].size);
-		skb_frag_ref(skb, j);
-	}
-	skb_shinfo(nskb)->nr_frags = k;
-
-	remaining_headlen = remaining - skb->data_len;
-
-	/* headlen contains remaining data? */
-	if (remaining_headlen > 0)
-		skb_copy_bits(skb, skb->len - remaining, nskb->data + headlen,
-			      remaining_headlen);
-	nskb->len = remaining + headlen;
-	nskb->data_len =  payload_len - sizeof(struct udphdr) +
-		max_t(int, 0, remaining_headlen);
-	nskb->protocol = skb->protocol;
-	if (nskb->protocol == htons(ETH_P_IP)) {
-		ip_hdr(nskb)->id = htons(ntohs(ip_hdr(nskb)->id) +
-					 skb_shinfo(skb)->gso_segs);
-		ip_hdr(nskb)->tot_len =
-			htons(payload_len + sizeof(struct iphdr));
-	} else {
-		ipv6_hdr(nskb)->payload_len = htons(payload_len);
-	}
-	udp_hdr(nskb)->len = htons(payload_len);
-	skb_shinfo(nskb)->gso_size = 0;
-	nskb->ip_summed = skb->ip_summed;
-	nskb->csum_start = skb->csum_start;
-	nskb->csum_offset = skb->csum_offset;
-	nskb->queue_mapping = skb->queue_mapping;
-}
-
-/* might send skbs and update wqe and pi */
-struct sk_buff *mlx5e_udp_gso_handle_tx_skb(struct net_device *netdev,
-					    struct mlx5e_txqsq *sq,
-					    struct sk_buff *skb,
-					    struct mlx5e_tx_wqe **wqe,
-					    u16 *pi)
-{
-	int payload_len = skb_shinfo(skb)->gso_size + sizeof(struct udphdr);
-	int headlen = skb_transport_offset(skb) + sizeof(struct udphdr);
-	int remaining = (skb->len - headlen) % skb_shinfo(skb)->gso_size;
-	struct sk_buff *nskb;
-
-	if (skb->protocol == htons(ETH_P_IP))
-		ip_hdr(skb)->tot_len = htons(payload_len + sizeof(struct iphdr));
-	else
-		ipv6_hdr(skb)->payload_len = htons(payload_len);
-	udp_hdr(skb)->len = htons(payload_len);
-	if (!remaining)
-		return skb;
-
-	sq->stats->udp_seg_rem++;
-	nskb = alloc_skb(max_t(int, headlen, headlen + remaining - skb->data_len), GFP_ATOMIC);
-	if (unlikely(!nskb)) {
-		sq->stats->dropped++;
-		return NULL;
-	}
-
-	mlx5e_udp_gso_prepare_last_skb(skb, nskb, remaining);
-
-	skb_shinfo(skb)->gso_segs--;
-	pskb_trim(skb, skb->len - remaining);
-	mlx5e_sq_xmit(sq, skb, *wqe, *pi);
-	mlx5e_sq_fetch_wqe(sq, wqe, pi);
-	return nskb;
-}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/rxtx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/rxtx.h
deleted file mode 100644
index ed42699a78b3..000000000000
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/rxtx.h
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#ifndef __MLX5E_EN_ACCEL_RX_TX_H__
-#define __MLX5E_EN_ACCEL_RX_TX_H__
-
-#include <linux/skbuff.h>
-#include "en.h"
-
-struct sk_buff *mlx5e_udp_gso_handle_tx_skb(struct net_device *netdev,
-					    struct mlx5e_txqsq *sq,
-					    struct sk_buff *skb,
-					    struct mlx5e_tx_wqe **wqe,
-					    u16 *pi);
-
-#endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 712b9766485f..dccde18f6170 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -4538,7 +4538,6 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
 	netdev->hw_features      |= NETIF_F_HW_VLAN_STAG_TX;
 
 	if (mlx5e_vxlan_allowed(mdev) || MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
-		netdev->hw_features     |= NETIF_F_GSO_PARTIAL;
 		netdev->hw_enc_features |= NETIF_F_IP_CSUM;
 		netdev->hw_enc_features |= NETIF_F_IPV6_CSUM;
 		netdev->hw_enc_features |= NETIF_F_TSO;
@@ -4563,6 +4562,11 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
 						NETIF_F_GSO_GRE_CSUM;
 	}
 
+	netdev->hw_features	                 |= NETIF_F_GSO_PARTIAL;
+	netdev->gso_partial_features             |= NETIF_F_GSO_UDP_L4;
+	netdev->hw_features                      |= NETIF_F_GSO_UDP_L4;
+	netdev->features                         |= NETIF_F_GSO_UDP_L4;
+
 	mlx5_query_port_fcs(mdev, &fcs_supported, &fcs_enabled);
 
 	if (fcs_supported)
@@ -4595,9 +4599,6 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
 	netdev->features         |= NETIF_F_HIGHDMA;
 	netdev->features         |= NETIF_F_HW_VLAN_STAG_FILTER;
 
-	netdev->features         |= NETIF_F_GSO_UDP_L4;
-	netdev->hw_features      |= NETIF_F_GSO_UDP_L4;
-
 	netdev->priv_flags       |= IFF_UNICAST_FLT;
 
 	mlx5e_set_netdev_dev_addr(netdev);
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 11/12] net/mlx5e: Support offloading double vlan push/pop tc actions
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Jianbo Liu, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

From: Jianbo Liu <jianbol@mellanox.com>

As we can configure two push/pop actions in one flow table entry,
add support to offload those double vlan actions in a rule to HW.

Signed-off-by: Jianbo Liu <jianbol@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../net/ethernet/mellanox/mlx5/core/en_tc.c   | 46 ++++++++++++++-----
 .../net/ethernet/mellanox/mlx5/core/eswitch.h | 21 ++++++---
 .../mellanox/mlx5/core/eswitch_offloads.c     | 11 +++--
 3 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 35b3e135ae1d..e9888d6c1f7c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -2583,24 +2583,48 @@ static int parse_tc_vlan_action(struct mlx5e_priv *priv,
 				struct mlx5_esw_flow_attr *attr,
 				u32 *action)
 {
+	u8 vlan_idx = attr->total_vlan;
+
+	if (vlan_idx >= MLX5_FS_VLAN_DEPTH)
+		return -EOPNOTSUPP;
+
 	if (tcf_vlan_action(a) == TCA_VLAN_ACT_POP) {
-		*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
+		if (vlan_idx) {
+			if (!mlx5_eswitch_vlan_actions_supported(priv->mdev,
+								 MLX5_FS_VLAN_DEPTH))
+				return -EOPNOTSUPP;
+
+			*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP_2;
+		} else {
+			*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
+		}
 	} else if (tcf_vlan_action(a) == TCA_VLAN_ACT_PUSH) {
-		*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
-		attr->vlan_vid[0] = tcf_vlan_push_vid(a);
-		if (mlx5_eswitch_vlan_actions_supported(priv->mdev)) {
-			attr->vlan_prio[0] = tcf_vlan_push_prio(a);
-			attr->vlan_proto[0] = tcf_vlan_push_proto(a);
-			if (!attr->vlan_proto[0])
-				attr->vlan_proto[0] = htons(ETH_P_8021Q);
-		} else if (tcf_vlan_push_proto(a) != htons(ETH_P_8021Q) ||
-			   tcf_vlan_push_prio(a)) {
-			return -EOPNOTSUPP;
+		attr->vlan_vid[vlan_idx] = tcf_vlan_push_vid(a);
+		attr->vlan_prio[vlan_idx] = tcf_vlan_push_prio(a);
+		attr->vlan_proto[vlan_idx] = tcf_vlan_push_proto(a);
+		if (!attr->vlan_proto[vlan_idx])
+			attr->vlan_proto[vlan_idx] = htons(ETH_P_8021Q);
+
+		if (vlan_idx) {
+			if (!mlx5_eswitch_vlan_actions_supported(priv->mdev,
+								 MLX5_FS_VLAN_DEPTH))
+				return -EOPNOTSUPP;
+
+			*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2;
+		} else {
+			if (!mlx5_eswitch_vlan_actions_supported(priv->mdev, 1) &&
+			    (tcf_vlan_push_proto(a) != htons(ETH_P_8021Q) ||
+			     tcf_vlan_push_prio(a)))
+				return -EOPNOTSUPP;
+
+			*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
 		}
 	} else { /* action is TCA_VLAN_ACT_MODIFY */
 		return -EOPNOTSUPP;
 	}
 
+	attr->total_vlan = vlan_idx + 1;
+
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index befa0011efee..c17bfcab517c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -38,6 +38,7 @@
 #include <net/devlink.h>
 #include <linux/mlx5/device.h>
 #include <linux/mlx5/eswitch.h>
+#include <linux/mlx5/fs.h>
 #include "lib/mpfs.h"
 
 #ifdef CONFIG_MLX5_ESWITCH
@@ -256,9 +257,10 @@ struct mlx5_esw_flow_attr {
 	int out_count;
 
 	int	action;
-	__be16	vlan_proto[1];
-	u16	vlan_vid[1];
-	u8	vlan_prio[1];
+	__be16	vlan_proto[MLX5_FS_VLAN_DEPTH];
+	u16	vlan_vid[MLX5_FS_VLAN_DEPTH];
+	u8	vlan_prio[MLX5_FS_VLAN_DEPTH];
+	u8	total_vlan;
 	bool	vlan_handled;
 	u32	encap_id;
 	u32	mod_hdr_id;
@@ -282,10 +284,17 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
 int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
 				  int vport, u16 vlan, u8 qos, u8 set_flags);
 
-static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev)
+static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev,
+						       u8 vlan_depth)
 {
-	return MLX5_CAP_ESW_FLOWTABLE_FDB(dev, pop_vlan) &&
-	       MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan);
+	bool ret = MLX5_CAP_ESW_FLOWTABLE_FDB(dev, pop_vlan) &&
+		   MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan);
+
+	if (vlan_depth == 1)
+		return ret;
+
+	return  ret && MLX5_CAP_ESW_FLOWTABLE_FDB(dev, pop_vlan_2) &&
+		MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan_2);
 }
 
 #define MLX5_DEBUG_ESWITCH_MASK BIT(3)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 552954d7184e..f72b5c9dcfe9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -66,13 +66,18 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
 
 	flow_act.action = attr->action;
 	/* if per flow vlan pop/push is emulated, don't set that into the firmware */
-	if (!mlx5_eswitch_vlan_actions_supported(esw->dev))
+	if (!mlx5_eswitch_vlan_actions_supported(esw->dev, 1))
 		flow_act.action &= ~(MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH |
 				     MLX5_FLOW_CONTEXT_ACTION_VLAN_POP);
 	else if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) {
 		flow_act.vlan[0].ethtype = ntohs(attr->vlan_proto[0]);
 		flow_act.vlan[0].vid = attr->vlan_vid[0];
 		flow_act.vlan[0].prio = attr->vlan_prio[0];
+		if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2) {
+			flow_act.vlan[1].ethtype = ntohs(attr->vlan_proto[1]);
+			flow_act.vlan[1].vid = attr->vlan_vid[1];
+			flow_act.vlan[1].prio = attr->vlan_prio[1];
+		}
 	}
 
 	if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
@@ -284,7 +289,7 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
 	int err = 0;
 
 	/* nop if we're on the vlan push/pop non emulation mode */
-	if (mlx5_eswitch_vlan_actions_supported(esw->dev))
+	if (mlx5_eswitch_vlan_actions_supported(esw->dev, 1))
 		return 0;
 
 	push = !!(attr->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH);
@@ -347,7 +352,7 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
 	int err = 0;
 
 	/* nop if we're on the vlan push/pop non emulation mode */
-	if (mlx5_eswitch_vlan_actions_supported(esw->dev))
+	if (mlx5_eswitch_vlan_actions_supported(esw->dev, 1))
 		return 0;
 
 	if (!attr->vlan_handled)
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 10/12] net/mlx5e: Refactor tc vlan push/pop actions offloading
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Jianbo Liu, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

From: Jianbo Liu <jianbol@mellanox.com>

Extract actions offloading code to a new function, and also extend data
structures for double vlan actions.

Signed-off-by: Jianbo Liu <jianbol@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../net/ethernet/mellanox/mlx5/core/en_tc.c   | 51 ++++++++++++-------
 .../net/ethernet/mellanox/mlx5/core/eswitch.h |  6 +--
 .../mellanox/mlx5/core/eswitch_offloads.c     | 12 ++---
 3 files changed, 41 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index dcb8c4993811..35b3e135ae1d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -2578,6 +2578,32 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
 	return err;
 }
 
+static int parse_tc_vlan_action(struct mlx5e_priv *priv,
+				const struct tc_action *a,
+				struct mlx5_esw_flow_attr *attr,
+				u32 *action)
+{
+	if (tcf_vlan_action(a) == TCA_VLAN_ACT_POP) {
+		*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
+	} else if (tcf_vlan_action(a) == TCA_VLAN_ACT_PUSH) {
+		*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
+		attr->vlan_vid[0] = tcf_vlan_push_vid(a);
+		if (mlx5_eswitch_vlan_actions_supported(priv->mdev)) {
+			attr->vlan_prio[0] = tcf_vlan_push_prio(a);
+			attr->vlan_proto[0] = tcf_vlan_push_proto(a);
+			if (!attr->vlan_proto[0])
+				attr->vlan_proto[0] = htons(ETH_P_8021Q);
+		} else if (tcf_vlan_push_proto(a) != htons(ETH_P_8021Q) ||
+			   tcf_vlan_push_prio(a)) {
+			return -EOPNOTSUPP;
+		}
+	} else { /* action is TCA_VLAN_ACT_MODIFY */
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
 static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
 				struct mlx5e_tc_flow_parse_attr *parse_attr,
 				struct mlx5e_tc_flow *flow)
@@ -2589,6 +2615,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
 	LIST_HEAD(actions);
 	bool encap = false;
 	u32 action = 0;
+	int err;
 
 	if (!tcf_exts_has_actions(exts))
 		return -EINVAL;
@@ -2605,8 +2632,6 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
 		}
 
 		if (is_tcf_pedit(a)) {
-			int err;
-
 			err = parse_tc_pedit_action(priv, a, MLX5_FLOW_NAMESPACE_FDB,
 						    parse_attr);
 			if (err)
@@ -2673,23 +2698,11 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
 		}
 
 		if (is_tcf_vlan(a)) {
-			if (tcf_vlan_action(a) == TCA_VLAN_ACT_POP) {
-				action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
-			} else if (tcf_vlan_action(a) == TCA_VLAN_ACT_PUSH) {
-				action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
-				attr->vlan_vid = tcf_vlan_push_vid(a);
-				if (mlx5_eswitch_vlan_actions_supported(priv->mdev)) {
-					attr->vlan_prio = tcf_vlan_push_prio(a);
-					attr->vlan_proto = tcf_vlan_push_proto(a);
-					if (!attr->vlan_proto)
-						attr->vlan_proto = htons(ETH_P_8021Q);
-				} else if (tcf_vlan_push_proto(a) != htons(ETH_P_8021Q) ||
-					   tcf_vlan_push_prio(a)) {
-					return -EOPNOTSUPP;
-				}
-			} else { /* action is TCA_VLAN_ACT_MODIFY */
-				return -EOPNOTSUPP;
-			}
+			err = parse_tc_vlan_action(priv, a, attr, &action);
+
+			if (err)
+				return err;
+
 			attr->mirror_count = attr->out_count;
 			continue;
 		}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index b174da2884c5..befa0011efee 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -256,9 +256,9 @@ struct mlx5_esw_flow_attr {
 	int out_count;
 
 	int	action;
-	__be16	vlan_proto;
-	u16	vlan_vid;
-	u8	vlan_prio;
+	__be16	vlan_proto[1];
+	u16	vlan_vid[1];
+	u8	vlan_prio[1];
 	bool	vlan_handled;
 	u32	encap_id;
 	u32	mod_hdr_id;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index f32e69170b30..552954d7184e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -70,9 +70,9 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
 		flow_act.action &= ~(MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH |
 				     MLX5_FLOW_CONTEXT_ACTION_VLAN_POP);
 	else if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) {
-		flow_act.vlan[0].ethtype = ntohs(attr->vlan_proto);
-		flow_act.vlan[0].vid = attr->vlan_vid;
-		flow_act.vlan[0].prio = attr->vlan_prio;
+		flow_act.vlan[0].ethtype = ntohs(attr->vlan_proto[0]);
+		flow_act.vlan[0].vid = attr->vlan_vid[0];
+		flow_act.vlan[0].prio = attr->vlan_prio[0];
 	}
 
 	if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
@@ -266,7 +266,7 @@ static int esw_add_vlan_action_check(struct mlx5_esw_flow_attr *attr,
 	/* protects against (1) setting rules with different vlans to push and
 	 * (2) setting rules w.o vlans (attr->vlan = 0) && w. vlans to push (!= 0)
 	 */
-	if (push && in_rep->vlan_refcount && (in_rep->vlan != attr->vlan_vid))
+	if (push && in_rep->vlan_refcount && (in_rep->vlan != attr->vlan_vid[0]))
 		goto out_notsupp;
 
 	return 0;
@@ -324,11 +324,11 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
 		if (vport->vlan_refcount)
 			goto skip_set_push;
 
-		err = __mlx5_eswitch_set_vport_vlan(esw, vport->vport, attr->vlan_vid, 0,
+		err = __mlx5_eswitch_set_vport_vlan(esw, vport->vport, attr->vlan_vid[0], 0,
 						    SET_VLAN_INSERT | SET_VLAN_STRIP);
 		if (err)
 			goto out;
-		vport->vlan = attr->vlan_vid;
+		vport->vlan = attr->vlan_vid[0];
 skip_set_push:
 		vport->vlan_refcount++;
 	}
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 09/12] net/mlx5e: Support offloading tc double vlan headers match
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Jianbo Liu, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

From: Jianbo Liu <jianbol@mellanox.com>

We can match on both outer and inner vlan tags, add support for
offloading that.

Signed-off-by: Jianbo Liu <jianbol@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../net/ethernet/mellanox/mlx5/core/en_tc.c   | 55 ++++++++++++++++++-
 1 file changed, 52 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 335a08bc381d..dcb8c4993811 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1235,6 +1235,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
 				       outer_headers);
 	void *headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
 				       outer_headers);
+	void *misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
+				    misc_parameters);
+	void *misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
+				    misc_parameters);
 	u16 addr_type = 0;
 	u8 ip_proto = 0;
 
@@ -1245,6 +1249,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
 	      BIT(FLOW_DISSECTOR_KEY_BASIC) |
 	      BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
 	      BIT(FLOW_DISSECTOR_KEY_VLAN) |
+	      BIT(FLOW_DISSECTOR_KEY_CVLAN) |
 	      BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
 	      BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
 	      BIT(FLOW_DISSECTOR_KEY_PORTS) |
@@ -1325,9 +1330,18 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
 			skb_flow_dissector_target(f->dissector,
 						  FLOW_DISSECTOR_KEY_VLAN,
 						  f->mask);
-		if (mask->vlan_id || mask->vlan_priority) {
-			MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1);
-			MLX5_SET(fte_match_set_lyr_2_4, headers_v, cvlan_tag, 1);
+		if (mask->vlan_id || mask->vlan_priority || mask->vlan_tpid) {
+			if (key->vlan_tpid == htons(ETH_P_8021AD)) {
+				MLX5_SET(fte_match_set_lyr_2_4, headers_c,
+					 svlan_tag, 1);
+				MLX5_SET(fte_match_set_lyr_2_4, headers_v,
+					 svlan_tag, 1);
+			} else {
+				MLX5_SET(fte_match_set_lyr_2_4, headers_c,
+					 cvlan_tag, 1);
+				MLX5_SET(fte_match_set_lyr_2_4, headers_v,
+					 cvlan_tag, 1);
+			}
 
 			MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_vid, mask->vlan_id);
 			MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_vid, key->vlan_id);
@@ -1339,6 +1353,41 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
 		}
 	}
 
+	if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CVLAN)) {
+		struct flow_dissector_key_vlan *key =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_CVLAN,
+						  f->key);
+		struct flow_dissector_key_vlan *mask =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_CVLAN,
+						  f->mask);
+		if (mask->vlan_id || mask->vlan_priority || mask->vlan_tpid) {
+			if (key->vlan_tpid == htons(ETH_P_8021AD)) {
+				MLX5_SET(fte_match_set_misc, misc_c,
+					 outer_second_svlan_tag, 1);
+				MLX5_SET(fte_match_set_misc, misc_v,
+					 outer_second_svlan_tag, 1);
+			} else {
+				MLX5_SET(fte_match_set_misc, misc_c,
+					 outer_second_cvlan_tag, 1);
+				MLX5_SET(fte_match_set_misc, misc_v,
+					 outer_second_cvlan_tag, 1);
+			}
+
+			MLX5_SET(fte_match_set_misc, misc_c, outer_second_vid,
+				 mask->vlan_id);
+			MLX5_SET(fte_match_set_misc, misc_v, outer_second_vid,
+				 key->vlan_id);
+			MLX5_SET(fte_match_set_misc, misc_c, outer_second_prio,
+				 mask->vlan_priority);
+			MLX5_SET(fte_match_set_misc, misc_v, outer_second_prio,
+				 key->vlan_priority);
+
+			*match_level = MLX5_MATCH_L2;
+		}
+	}
+
 	if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
 		struct flow_dissector_key_basic *key =
 			skb_flow_dissector_target(f->dissector,
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 08/12] net/mlx5e: Remove redundant WARN when we cannot find neigh entry
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Roi Dayan, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

From: Roi Dayan <roid@mellanox.com>

It is possible for neigh entry not to exist if it was cleaned already.
When we bring down an interface the neigh gets deleted but it could be
that our listener for neigh event to clear the encap valid bit didn't
start yet and the neigh update last used work is started first.
In this scenario the encap entry has valid bit set but the neigh entry
doesn't exist.

Signed-off-by: Roi Dayan <roid@mellanox.com>
Reviewed-by: Paul Blakey <paulb@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 0edf4751a8ba..335a08bc381d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1032,10 +1032,8 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
 		 * dst ip pair
 		 */
 		n = neigh_lookup(tbl, &m_neigh->dst_ip, m_neigh->dev);
-		if (!n) {
-			WARN(1, "The neighbour already freed\n");
+		if (!n)
 			return;
-		}
 
 		neigh_event_send(n, NULL);
 		neigh_release(n);
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 06/12] net/mlx5: FW tracer, Enable tracing
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Feras Daoud, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

From: Feras Daoud <ferasda@mellanox.com>

Add the tracer file to the makefile and add the init
function to the load one flow.

Signed-off-by: Feras Daoud <ferasda@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../net/ethernet/mellanox/mlx5/core/Makefile   |  2 +-
 .../mellanox/mlx5/core/diag/fw_tracer.h        |  2 +-
 drivers/net/ethernet/mellanox/mlx5/core/main.c | 18 ++++++++++++++++--
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index d923f2f58608..55d5a5c2e9d8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -6,7 +6,7 @@ mlx5_core-y :=	main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
 		health.o mcg.o cq.o srq.o alloc.o qp.o port.o mr.o pd.o \
 		mad.o transobj.o vport.o sriov.o fs_cmd.o fs_core.o \
 		fs_counters.o rl.o lag.o dev.o wq.o lib/gid.o lib/clock.o \
-		diag/fs_tracepoint.o
+		diag/fs_tracepoint.o diag/fw_tracer.o
 
 mlx5_core-$(CONFIG_MLX5_ACCEL) += accel/ipsec.o accel/tls.o
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
index 8d310e7d6743..0347f2dd5cee 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
@@ -170,6 +170,6 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev);
 int mlx5_fw_tracer_init(struct mlx5_fw_tracer *tracer);
 void mlx5_fw_tracer_cleanup(struct mlx5_fw_tracer *tracer);
 void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer);
-void mlx5_fw_tracer_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe) { return; }
+void mlx5_fw_tracer_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe);
 
 #endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index f9b950e1bd85..6ddbb70e95de 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -62,6 +62,7 @@
 #include "accel/ipsec.h"
 #include "accel/tls.h"
 #include "lib/clock.h"
+#include "diag/fw_tracer.h"
 
 MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
 MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) core driver");
@@ -990,6 +991,8 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
 		goto err_sriov_cleanup;
 	}
 
+	dev->tracer = mlx5_fw_tracer_create(dev);
+
 	return 0;
 
 err_sriov_cleanup:
@@ -1015,6 +1018,7 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
 
 static void mlx5_cleanup_once(struct mlx5_core_dev *dev)
 {
+	mlx5_fw_tracer_destroy(dev->tracer);
 	mlx5_fpga_cleanup(dev);
 	mlx5_sriov_cleanup(dev);
 	mlx5_eswitch_cleanup(dev->priv.eswitch);
@@ -1167,10 +1171,16 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
 		goto err_put_uars;
 	}
 
+	err = mlx5_fw_tracer_init(dev->tracer);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to init FW tracer\n");
+		goto err_fw_tracer;
+	}
+
 	err = alloc_comp_eqs(dev);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to alloc completion EQs\n");
-		goto err_stop_eqs;
+		goto err_comp_eqs;
 	}
 
 	err = mlx5_irq_set_affinity_hints(dev);
@@ -1252,7 +1262,10 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
 err_affinity_hints:
 	free_comp_eqs(dev);
 
-err_stop_eqs:
+err_comp_eqs:
+	mlx5_fw_tracer_cleanup(dev->tracer);
+
+err_fw_tracer:
 	mlx5_stop_eqs(dev);
 
 err_put_uars:
@@ -1320,6 +1333,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
 	mlx5_fpga_device_stop(dev);
 	mlx5_irq_clear_affinity_hints(dev);
 	free_comp_eqs(dev);
+	mlx5_fw_tracer_cleanup(dev->tracer);
 	mlx5_stop_eqs(dev);
 	mlx5_put_uars_page(dev, priv->uar);
 	mlx5_free_irq_vectors(dev);
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 07/12] net/mlx5: FW tracer, Add debug prints
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../ethernet/mellanox/mlx5/core/diag/fw_tracer.c    | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
index 309842de272c..d4ec93bde4de 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
@@ -629,14 +629,14 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work)
 	u64 block_timestamp, last_block_timestamp, tmp_trace_block[TRACES_PER_BLOCK];
 	u32 block_count, start_offset, prev_start_offset, prev_consumer_index;
 	u32 trace_event_size = MLX5_ST_SZ_BYTES(tracer_event);
+	struct mlx5_core_dev *dev = tracer->dev;
 	struct tracer_event tracer_event;
-	struct mlx5_core_dev *dev;
 	int i;
 
+	mlx5_core_dbg(dev, "FWTracer: Handle Trace event, owner=(%d)\n", tracer->owner);
 	if (!tracer->owner)
 		return;
 
-	dev = tracer->dev;
 	block_count = tracer->buff.size / TRACER_BLOCK_SIZE_BYTE;
 	start_offset = tracer->buff.consumer_index * TRACER_BLOCK_SIZE_BYTE;
 
@@ -762,6 +762,7 @@ static int mlx5_fw_tracer_start(struct mlx5_fw_tracer *tracer)
 		goto release_ownership;
 	}
 
+	mlx5_core_dbg(dev, "FWTracer: Ownership granted and active\n");
 	return 0;
 
 release_ownership:
@@ -774,6 +775,7 @@ static void mlx5_fw_tracer_ownership_change(struct work_struct *work)
 	struct mlx5_fw_tracer *tracer =
 		container_of(work, struct mlx5_fw_tracer, ownership_change_work);
 
+	mlx5_core_dbg(tracer->dev, "FWTracer: ownership changed, current=(%d)\n", tracer->owner);
 	if (tracer->owner) {
 		tracer->owner = false;
 		tracer->buff.consumer_index = 0;
@@ -830,6 +832,8 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
 		goto free_log_buf;
 	}
 
+	mlx5_core_dbg(dev, "FWTracer: Tracer created\n");
+
 	return tracer;
 
 free_log_buf:
@@ -887,6 +891,9 @@ void mlx5_fw_tracer_cleanup(struct mlx5_fw_tracer *tracer)
 	if (IS_ERR_OR_NULL(tracer))
 		return;
 
+	mlx5_core_dbg(tracer->dev, "FWTracer: Cleanup, is owner ? (%d)\n",
+		      tracer->owner);
+
 	cancel_work_sync(&tracer->ownership_change_work);
 	cancel_work_sync(&tracer->handle_traces_work);
 
@@ -903,6 +910,8 @@ void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer)
 	if (IS_ERR_OR_NULL(tracer))
 		return;
 
+	mlx5_core_dbg(tracer->dev, "FWTracer: Destroy\n");
+
 	cancel_work_sync(&tracer->read_fw_strings_work);
 	mlx5_fw_tracer_clean_ready_list(tracer);
 	mlx5_fw_tracer_clean_print_hash(tracer);
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 04/12] net/mlx5: FW tracer, events handling
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Feras Daoud, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

From: Feras Daoud <ferasda@mellanox.com>

The tracer has one event, event 0x26, with two subtypes:
- Subtype 0: Ownership change
- Subtype 1: Traces available

An ownership change occurs in the following cases:
1- Owner releases his ownership, in this case, an event will be
sent to inform others to reattempt acquire ownership.
2- Ownership was taken by a higher priority tool, in this case
the owner should understand that it lost ownership, and go through
tear down flow.

The second subtype indicates that there are traces in the trace buffer,
in this case, the driver polls the tracer buffer for new traces, parse
them and prepares the messages for printing.

The HW starts tracing from the first address in the tracer buffer.
Driver receives an event notifying that new trace block exists.
HW posts a timestamp event at the last 8B of every 256B block.
Comparing the timestamp to the last handled timestamp would indicate
that this is a new trace block. Once the new timestamp is detected,
the entire block is considered valid.

Block validation and parsing, should be done after copying the current
block to a different location, in order to avoid block overwritten
during processing.

Signed-off-by: Feras Daoud <ferasda@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../mellanox/mlx5/core/diag/fw_tracer.c       | 268 +++++++++++++++++-
 .../mellanox/mlx5/core/diag/fw_tracer.h       |  71 ++++-
 drivers/net/ethernet/mellanox/mlx5/core/eq.c  |  11 +
 include/linux/mlx5/device.h                   |   7 +
 4 files changed, 347 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
index d6cc27b0ff34..bd887d1d3396 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
@@ -318,25 +318,244 @@ static void mlx5_tracer_read_strings_db(struct work_struct *work)
 	return;
 }
 
-static void mlx5_fw_tracer_ownership_change(struct work_struct *work)
+static void mlx5_fw_tracer_arm(struct mlx5_core_dev *dev)
 {
-	struct mlx5_fw_tracer *tracer = container_of(work, struct mlx5_fw_tracer,
-						     ownership_change_work);
-	struct mlx5_core_dev *dev = tracer->dev;
+	u32 out[MLX5_ST_SZ_DW(mtrc_ctrl)] = {0};
+	u32 in[MLX5_ST_SZ_DW(mtrc_ctrl)] = {0};
 	int err;
 
-	if (tracer->owner) {
-		mlx5_fw_tracer_ownership_release(tracer);
+	MLX5_SET(mtrc_ctrl, in, arm_event, 1);
+
+	err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
+				   MLX5_REG_MTRC_CTRL, 0, 1);
+	if (err)
+		mlx5_core_warn(dev, "FWTracer: Failed to arm tracer event %d\n", err);
+}
+
+static void poll_trace(struct mlx5_fw_tracer *tracer,
+		       struct tracer_event *tracer_event, u64 *trace)
+{
+	u32 timestamp_low, timestamp_mid, timestamp_high, urts;
+
+	tracer_event->event_id = MLX5_GET(tracer_event, trace, event_id);
+	tracer_event->lost_event = MLX5_GET(tracer_event, trace, lost);
+
+	switch (tracer_event->event_id) {
+	case TRACER_EVENT_TYPE_TIMESTAMP:
+		tracer_event->type = TRACER_EVENT_TYPE_TIMESTAMP;
+		urts = MLX5_GET(tracer_timestamp_event, trace, urts);
+		if (tracer->trc_ver == 0)
+			tracer_event->timestamp_event.unreliable = !!(urts >> 2);
+		else
+			tracer_event->timestamp_event.unreliable = !!(urts & 1);
+
+		timestamp_low = MLX5_GET(tracer_timestamp_event,
+					 trace, timestamp7_0);
+		timestamp_mid = MLX5_GET(tracer_timestamp_event,
+					 trace, timestamp39_8);
+		timestamp_high = MLX5_GET(tracer_timestamp_event,
+					  trace, timestamp52_40);
+
+		tracer_event->timestamp_event.timestamp =
+				((u64)timestamp_high << 40) |
+				((u64)timestamp_mid << 8) |
+				(u64)timestamp_low;
+		break;
+	default:
+		if (tracer_event->event_id >= tracer->str_db.first_string_trace ||
+		    tracer_event->event_id <= tracer->str_db.first_string_trace +
+					      tracer->str_db.num_string_trace) {
+			tracer_event->type = TRACER_EVENT_TYPE_STRING;
+			tracer_event->string_event.timestamp =
+				MLX5_GET(tracer_string_event, trace, timestamp);
+			tracer_event->string_event.string_param =
+				MLX5_GET(tracer_string_event, trace, string_param);
+			tracer_event->string_event.tmsn =
+				MLX5_GET(tracer_string_event, trace, tmsn);
+			tracer_event->string_event.tdsn =
+				MLX5_GET(tracer_string_event, trace, tdsn);
+		} else {
+			tracer_event->type = TRACER_EVENT_TYPE_UNRECOGNIZED;
+		}
+		break;
+	}
+}
+
+static u64 get_block_timestamp(struct mlx5_fw_tracer *tracer, u64 *ts_event)
+{
+	struct tracer_event tracer_event;
+	u8 event_id;
+
+	event_id = MLX5_GET(tracer_event, ts_event, event_id);
+
+	if (event_id == TRACER_EVENT_TYPE_TIMESTAMP)
+		poll_trace(tracer, &tracer_event, ts_event);
+	else
+		tracer_event.timestamp_event.timestamp = 0;
+
+	return tracer_event.timestamp_event.timestamp;
+}
+
+static void mlx5_fw_tracer_handle_traces(struct work_struct *work)
+{
+	struct mlx5_fw_tracer *tracer =
+			container_of(work, struct mlx5_fw_tracer, handle_traces_work);
+	u64 block_timestamp, last_block_timestamp, tmp_trace_block[TRACES_PER_BLOCK];
+	u32 block_count, start_offset, prev_start_offset, prev_consumer_index;
+	u32 trace_event_size = MLX5_ST_SZ_BYTES(tracer_event);
+	struct tracer_event tracer_event;
+	struct mlx5_core_dev *dev;
+	int i;
+
+	if (!tracer->owner)
 		return;
+
+	dev = tracer->dev;
+	block_count = tracer->buff.size / TRACER_BLOCK_SIZE_BYTE;
+	start_offset = tracer->buff.consumer_index * TRACER_BLOCK_SIZE_BYTE;
+
+	/* Copy the block to local buffer to avoid HW override while being processed*/
+	memcpy(tmp_trace_block, tracer->buff.log_buf + start_offset,
+	       TRACER_BLOCK_SIZE_BYTE);
+
+	block_timestamp =
+		get_block_timestamp(tracer, &tmp_trace_block[TRACES_PER_BLOCK - 1]);
+
+	while (block_timestamp > tracer->last_timestamp) {
+		/* Check block override if its not the first block */
+		if (!tracer->last_timestamp) {
+			u64 *ts_event;
+			/* To avoid block override be the HW in case of buffer
+			 * wraparound, the time stamp of the previous block
+			 * should be compared to the last timestamp handled
+			 * by the driver.
+			 */
+			prev_consumer_index =
+				(tracer->buff.consumer_index - 1) & (block_count - 1);
+			prev_start_offset = prev_consumer_index * TRACER_BLOCK_SIZE_BYTE;
+
+			ts_event = tracer->buff.log_buf + prev_start_offset +
+				   (TRACES_PER_BLOCK - 1) * trace_event_size;
+			last_block_timestamp = get_block_timestamp(tracer, ts_event);
+			/* If previous timestamp different from last stored
+			 * timestamp then there is a good chance that the
+			 * current buffer is overwritten and therefore should
+			 * not be parsed.
+			 */
+			if (tracer->last_timestamp != last_block_timestamp) {
+				mlx5_core_warn(dev, "FWTracer: Events were lost\n");
+				tracer->last_timestamp = block_timestamp;
+				tracer->buff.consumer_index =
+					(tracer->buff.consumer_index + 1) & (block_count - 1);
+				break;
+			}
+		}
+
+		/* Parse events */
+		for (i = 0; i < TRACES_PER_BLOCK ; i++)
+			poll_trace(tracer, &tracer_event, &tmp_trace_block[i]);
+
+		tracer->buff.consumer_index =
+			(tracer->buff.consumer_index + 1) & (block_count - 1);
+
+		tracer->last_timestamp = block_timestamp;
+		start_offset = tracer->buff.consumer_index * TRACER_BLOCK_SIZE_BYTE;
+		memcpy(tmp_trace_block, tracer->buff.log_buf + start_offset,
+		       TRACER_BLOCK_SIZE_BYTE);
+		block_timestamp = get_block_timestamp(tracer,
+						      &tmp_trace_block[TRACES_PER_BLOCK - 1]);
 	}
 
+	mlx5_fw_tracer_arm(dev);
+}
+
+static int mlx5_fw_tracer_set_mtrc_conf(struct mlx5_fw_tracer *tracer)
+{
+	struct mlx5_core_dev *dev = tracer->dev;
+	u32 out[MLX5_ST_SZ_DW(mtrc_conf)] = {0};
+	u32 in[MLX5_ST_SZ_DW(mtrc_conf)] = {0};
+	int err;
+
+	MLX5_SET(mtrc_conf, in, trace_mode, TRACE_TO_MEMORY);
+	MLX5_SET(mtrc_conf, in, log_trace_buffer_size,
+		 ilog2(TRACER_BUFFER_PAGE_NUM));
+	MLX5_SET(mtrc_conf, in, trace_mkey, tracer->buff.mkey.key);
+
+	err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
+				   MLX5_REG_MTRC_CONF, 0, 1);
+	if (err)
+		mlx5_core_warn(dev, "FWTracer: Failed to set tracer configurations %d\n", err);
+
+	return err;
+}
+
+static int mlx5_fw_tracer_set_mtrc_ctrl(struct mlx5_fw_tracer *tracer, u8 status, u8 arm)
+{
+	struct mlx5_core_dev *dev = tracer->dev;
+	u32 out[MLX5_ST_SZ_DW(mtrc_ctrl)] = {0};
+	u32 in[MLX5_ST_SZ_DW(mtrc_ctrl)] = {0};
+	int err;
+
+	MLX5_SET(mtrc_ctrl, in, modify_field_select, TRACE_STATUS);
+	MLX5_SET(mtrc_ctrl, in, trace_status, status);
+	MLX5_SET(mtrc_ctrl, in, arm_event, arm);
+
+	err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
+				   MLX5_REG_MTRC_CTRL, 0, 1);
+
+	if (!err && status)
+		tracer->last_timestamp = 0;
+
+	return err;
+}
+
+static int mlx5_fw_tracer_start(struct mlx5_fw_tracer *tracer)
+{
+	struct mlx5_core_dev *dev = tracer->dev;
+	int err;
+
 	err = mlx5_fw_tracer_ownership_acquire(tracer);
 	if (err) {
 		mlx5_core_dbg(dev, "FWTracer: Ownership was not granted %d\n", err);
+		/* Don't fail since ownership can be acquired on a later FW event */
+		return 0;
+	}
+
+	err = mlx5_fw_tracer_set_mtrc_conf(tracer);
+	if (err) {
+		mlx5_core_warn(dev, "FWTracer: Failed to set tracer configuration %d\n", err);
+		goto release_ownership;
+	}
+
+	/* enable tracer & trace events */
+	err = mlx5_fw_tracer_set_mtrc_ctrl(tracer, 1, 1);
+	if (err) {
+		mlx5_core_warn(dev, "FWTracer: Failed to enable tracer %d\n", err);
+		goto release_ownership;
+	}
+
+	return 0;
+
+release_ownership:
+	mlx5_fw_tracer_ownership_release(tracer);
+	return err;
+}
+
+static void mlx5_fw_tracer_ownership_change(struct work_struct *work)
+{
+	struct mlx5_fw_tracer *tracer =
+		container_of(work, struct mlx5_fw_tracer, ownership_change_work);
+
+	if (tracer->owner) {
+		tracer->owner = false;
+		tracer->buff.consumer_index = 0;
 		return;
 	}
+
+	mlx5_fw_tracer_start(tracer);
 }
 
+/* Create software resources (Buffers, etc ..) */
 struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
 {
 	struct mlx5_fw_tracer *tracer = NULL;
@@ -361,6 +580,8 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
 
 	INIT_WORK(&tracer->ownership_change_work, mlx5_fw_tracer_ownership_change);
 	INIT_WORK(&tracer->read_fw_strings_work, mlx5_tracer_read_strings_db);
+	INIT_WORK(&tracer->handle_traces_work, mlx5_fw_tracer_handle_traces);
+
 
 	err = mlx5_query_mtrc_caps(tracer);
 	if (err) {
@@ -392,6 +613,9 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
 	return ERR_PTR(err);
 }
 
+/* Create HW resources + start tracer
+ * must be called before Async EQ is created
+ */
 int mlx5_fw_tracer_init(struct mlx5_fw_tracer *tracer)
 {
 	struct mlx5_core_dev *dev;
@@ -417,22 +641,25 @@ int mlx5_fw_tracer_init(struct mlx5_fw_tracer *tracer)
 		goto err_dealloc_pd;
 	}
 
-	err = mlx5_fw_tracer_ownership_acquire(tracer);
-	if (err) /* Don't fail since ownership can be acquired on a later FW event */
-		mlx5_core_dbg(dev, "FWTracer: Ownership was not granted %d\n", err);
+	mlx5_fw_tracer_start(tracer);
 
 	return 0;
+
 err_dealloc_pd:
 	mlx5_core_dealloc_pd(dev, tracer->buff.pdn);
 	return err;
 }
 
+/* Stop tracer + Cleanup HW resources
+ * must be called after Async EQ is destroyed
+ */
 void mlx5_fw_tracer_cleanup(struct mlx5_fw_tracer *tracer)
 {
 	if (IS_ERR_OR_NULL(tracer))
 		return;
 
 	cancel_work_sync(&tracer->ownership_change_work);
+	cancel_work_sync(&tracer->handle_traces_work);
 
 	if (tracer->owner)
 		mlx5_fw_tracer_ownership_release(tracer);
@@ -441,6 +668,7 @@ void mlx5_fw_tracer_cleanup(struct mlx5_fw_tracer *tracer)
 	mlx5_core_dealloc_pd(tracer->dev, tracer->buff.pdn);
 }
 
+/* Free software resources (Buffers, etc ..) */
 void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer)
 {
 	if (IS_ERR_OR_NULL(tracer))
@@ -454,4 +682,26 @@ void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer)
 	kfree(tracer);
 }
 
+void mlx5_fw_tracer_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe)
+{
+	struct mlx5_fw_tracer *tracer = dev->tracer;
+
+	if (!tracer)
+		return;
+
+	switch (eqe->sub_type) {
+	case MLX5_TRACER_SUBTYPE_OWNERSHIP_CHANGE:
+		if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state))
+			queue_work(tracer->work_queue, &tracer->ownership_change_work);
+		break;
+	case MLX5_TRACER_SUBTYPE_TRACES_AVAILABLE:
+		if (likely(tracer->str_db.loaded))
+			queue_work(tracer->work_queue, &tracer->handle_traces_work);
+		break;
+	default:
+		mlx5_core_dbg(dev, "FWTracer: Event with unrecognized subtype: sub_type %d\n",
+			      eqe->sub_type);
+	}
+}
+
 EXPORT_TRACEPOINT_SYMBOL(mlx5_fw);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
index 66cb7e7ada28..3915e91486b2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
@@ -43,6 +43,9 @@
 #define TRACER_BUFFER_CHUNK 4096
 #define TRACE_BUFFER_SIZE_BYTE (TRACER_BUFFER_PAGE_NUM * TRACER_BUFFER_CHUNK)
 
+#define TRACER_BLOCK_SIZE_BYTE 256
+#define TRACES_PER_BLOCK 32
+
 struct mlx5_fw_tracer {
 	struct mlx5_core_dev *dev;
 	bool owner;
@@ -69,8 +72,11 @@ struct mlx5_fw_tracer {
 		dma_addr_t dma;
 		u32 size;
 		struct mlx5_core_mkey mkey;
-
+		u32 consumer_index;
 	} buff;
+
+	u64 last_timestamp;
+	struct work_struct handle_traces_work;
 };
 
 enum mlx5_fw_tracer_ownership_state {
@@ -78,7 +84,70 @@ enum mlx5_fw_tracer_ownership_state {
 	MLX5_FW_TRACER_ACQUIRE_OWNERSHIP,
 };
 
+enum tracer_ctrl_fields_select {
+	TRACE_STATUS = 1 << 0,
+};
+
+enum tracer_event_type {
+	TRACER_EVENT_TYPE_STRING,
+	TRACER_EVENT_TYPE_TIMESTAMP = 0xFF,
+	TRACER_EVENT_TYPE_UNRECOGNIZED,
+};
+
+enum tracing_mode {
+	TRACE_TO_MEMORY = 1 << 0,
+};
+
+struct tracer_timestamp_event {
+	u64        timestamp;
+	u8         unreliable;
+};
+
+struct tracer_string_event {
+	u32        timestamp;
+	u32        tmsn;
+	u32        tdsn;
+	u32        string_param;
+};
+
+struct tracer_event {
+	bool      lost_event;
+	u32       type;
+	u8        event_id;
+	union {
+		struct tracer_string_event string_event;
+		struct tracer_timestamp_event timestamp_event;
+	};
+};
+
+struct mlx5_ifc_tracer_event_bits {
+	u8         lost[0x1];
+	u8         timestamp[0x7];
+	u8         event_id[0x8];
+	u8         event_data[0x30];
+};
+
+struct mlx5_ifc_tracer_string_event_bits {
+	u8         lost[0x1];
+	u8         timestamp[0x7];
+	u8         event_id[0x8];
+	u8         tmsn[0xd];
+	u8         tdsn[0x3];
+	u8         string_param[0x20];
+};
+
+struct mlx5_ifc_tracer_timestamp_event_bits {
+	u8         timestamp7_0[0x8];
+	u8         event_id[0x8];
+	u8         urts[0x3];
+	u8         timestamp52_40[0xd];
+	u8         timestamp39_8[0x20];
+};
+
 struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev);
+int mlx5_fw_tracer_init(struct mlx5_fw_tracer *tracer);
+void mlx5_fw_tracer_cleanup(struct mlx5_fw_tracer *tracer);
 void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer);
+void mlx5_fw_tracer_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe) { return; }
 
 #endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index 406c23862f5f..7669b4380779 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -40,6 +40,7 @@
 #include "mlx5_core.h"
 #include "fpga/core.h"
 #include "eswitch.h"
+#include "diag/fw_tracer.h"
 
 enum {
 	MLX5_EQE_SIZE		= sizeof(struct mlx5_eqe),
@@ -168,6 +169,8 @@ static const char *eqe_type_str(u8 type)
 		return "MLX5_EVENT_TYPE_FPGA_QP_ERROR";
 	case MLX5_EVENT_TYPE_GENERAL_EVENT:
 		return "MLX5_EVENT_TYPE_GENERAL_EVENT";
+	case MLX5_EVENT_TYPE_DEVICE_TRACER:
+		return "MLX5_EVENT_TYPE_DEVICE_TRACER";
 	default:
 		return "Unrecognized event";
 	}
@@ -576,6 +579,11 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
 		case MLX5_EVENT_TYPE_GENERAL_EVENT:
 			general_event_handler(dev, eqe);
 			break;
+
+		case MLX5_EVENT_TYPE_DEVICE_TRACER:
+			mlx5_fw_tracer_event(dev, eqe);
+			break;
+
 		default:
 			mlx5_core_warn(dev, "Unhandled event 0x%x on EQ 0x%x\n",
 				       eqe->type, eq->eqn);
@@ -853,6 +861,9 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
 	if (MLX5_CAP_GEN(dev, temp_warn_event))
 		async_event_mask |= (1ull << MLX5_EVENT_TYPE_TEMP_WARN_EVENT);
 
+	if (MLX5_CAP_MCAM_REG(dev, tracer_registers))
+		async_event_mask |= (1ull << MLX5_EVENT_TYPE_DEVICE_TRACER);
+
 	err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD,
 				 MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD,
 				 "mlx5_cmd_eq", MLX5_EQ_TYPE_ASYNC);
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 0566c6a94805..d489494b0a84 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -332,6 +332,13 @@ enum mlx5_event {
 
 	MLX5_EVENT_TYPE_FPGA_ERROR         = 0x20,
 	MLX5_EVENT_TYPE_FPGA_QP_ERROR      = 0x21,
+
+	MLX5_EVENT_TYPE_DEVICE_TRACER      = 0x26,
+};
+
+enum {
+	MLX5_TRACER_SUBTYPE_OWNERSHIP_CHANGE = 0x0,
+	MLX5_TRACER_SUBTYPE_TRACES_AVAILABLE = 0x1,
 };
 
 enum {
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 05/12] net/mlx5: FW tracer, parse traces and kernel tracing support
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Feras Daoud, Erez Shitrit, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

From: Feras Daoud <ferasda@mellanox.com>

For each message the driver should do the following:
1- Find the message string in the strings database
2- Count the param number of each message
3- Wait for the param events and accumulate them
4- Calculate the event timestamp using the local event timestamp
and the first timestamp event following it.
5- Print message to trace log

Enable the tracing by:
echo 1 > /sys/kernel/debug/tracing/events/mlx5/mlx5_fw/enable

Read traces by:
cat /sys/kernel/debug/tracing/trace

Signed-off-by: Feras Daoud <ferasda@mellanox.com>
Signed-off-by: Erez Shitrit <erezsh@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../mellanox/mlx5/core/diag/fw_tracer.c       | 235 +++++++++++++++++-
 .../mellanox/mlx5/core/diag/fw_tracer.h       |  22 ++
 .../mlx5/core/diag/fw_tracer_tracepoint.h     |  78 ++++++
 3 files changed, 333 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer_tracepoint.h

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
index bd887d1d3396..309842de272c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
@@ -29,8 +29,9 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-
+#define CREATE_TRACE_POINTS
 #include "fw_tracer.h"
+#include "fw_tracer_tracepoint.h"
 
 static int mlx5_query_mtrc_caps(struct mlx5_fw_tracer *tracer)
 {
@@ -332,6 +333,109 @@ static void mlx5_fw_tracer_arm(struct mlx5_core_dev *dev)
 		mlx5_core_warn(dev, "FWTracer: Failed to arm tracer event %d\n", err);
 }
 
+static const char *VAL_PARM		= "%llx";
+static const char *REPLACE_64_VAL_PARM	= "%x%x";
+static const char *PARAM_CHAR		= "%";
+
+static int mlx5_tracer_message_hash(u32 message_id)
+{
+	return jhash_1word(message_id, 0) & (MESSAGE_HASH_SIZE - 1);
+}
+
+static struct tracer_string_format *mlx5_tracer_message_insert(struct mlx5_fw_tracer *tracer,
+							       struct tracer_event *tracer_event)
+{
+	struct hlist_head *head =
+		&tracer->hash[mlx5_tracer_message_hash(tracer_event->string_event.tmsn)];
+	struct tracer_string_format *cur_string;
+
+	cur_string = kzalloc(sizeof(*cur_string), GFP_KERNEL);
+	if (!cur_string)
+		return NULL;
+
+	hlist_add_head(&cur_string->hlist, head);
+
+	return cur_string;
+}
+
+static struct tracer_string_format *mlx5_tracer_get_string(struct mlx5_fw_tracer *tracer,
+							   struct tracer_event *tracer_event)
+{
+	struct tracer_string_format *cur_string;
+	u32 str_ptr, offset;
+	int i;
+
+	str_ptr = tracer_event->string_event.string_param;
+
+	for (i = 0; i < tracer->str_db.num_string_db; i++) {
+		if (str_ptr > tracer->str_db.base_address_out[i] &&
+		    str_ptr < tracer->str_db.base_address_out[i] +
+		    tracer->str_db.size_out[i]) {
+			offset = str_ptr - tracer->str_db.base_address_out[i];
+			/* add it to the hash */
+			cur_string = mlx5_tracer_message_insert(tracer, tracer_event);
+			if (!cur_string)
+				return NULL;
+			cur_string->string = (char *)(tracer->str_db.buffer[i] +
+							offset);
+			return cur_string;
+		}
+	}
+
+	return NULL;
+}
+
+static void mlx5_tracer_clean_message(struct tracer_string_format *str_frmt)
+{
+	hlist_del(&str_frmt->hlist);
+	kfree(str_frmt);
+}
+
+static int mlx5_tracer_get_num_of_params(char *str)
+{
+	char *substr, *pstr = str;
+	int num_of_params = 0;
+
+	/* replace %llx with %x%x */
+	substr = strstr(pstr, VAL_PARM);
+	while (substr) {
+		memcpy(substr, REPLACE_64_VAL_PARM, 4);
+		pstr = substr;
+		substr = strstr(pstr, VAL_PARM);
+	}
+
+	/* count all the % characters */
+	substr = strstr(str, PARAM_CHAR);
+	while (substr) {
+		num_of_params += 1;
+		str = substr + 1;
+		substr = strstr(str, PARAM_CHAR);
+	}
+
+	return num_of_params;
+}
+
+static struct tracer_string_format *mlx5_tracer_message_find(struct hlist_head *head,
+							     u8 event_id, u32 tmsn)
+{
+	struct tracer_string_format *message;
+
+	hlist_for_each_entry(message, head, hlist)
+		if (message->event_id == event_id && message->tmsn == tmsn)
+			return message;
+
+	return NULL;
+}
+
+static struct tracer_string_format *mlx5_tracer_message_get(struct mlx5_fw_tracer *tracer,
+							    struct tracer_event *tracer_event)
+{
+	struct hlist_head *head =
+		&tracer->hash[mlx5_tracer_message_hash(tracer_event->string_event.tmsn)];
+
+	return mlx5_tracer_message_find(head, tracer_event->event_id, tracer_event->string_event.tmsn);
+}
+
 static void poll_trace(struct mlx5_fw_tracer *tracer,
 		       struct tracer_event *tracer_event, u64 *trace)
 {
@@ -396,6 +500,128 @@ static u64 get_block_timestamp(struct mlx5_fw_tracer *tracer, u64 *ts_event)
 	return tracer_event.timestamp_event.timestamp;
 }
 
+static void mlx5_fw_tracer_clean_print_hash(struct mlx5_fw_tracer *tracer)
+{
+	struct tracer_string_format *str_frmt;
+	struct hlist_node *n;
+	int i;
+
+	for (i = 0; i < MESSAGE_HASH_SIZE; i++) {
+		hlist_for_each_entry_safe(str_frmt, n, &tracer->hash[i], hlist)
+			mlx5_tracer_clean_message(str_frmt);
+	}
+}
+
+static void mlx5_fw_tracer_clean_ready_list(struct mlx5_fw_tracer *tracer)
+{
+	struct tracer_string_format *str_frmt, *tmp_str;
+
+	list_for_each_entry_safe(str_frmt, tmp_str, &tracer->ready_strings_list,
+				 list)
+		list_del(&str_frmt->list);
+}
+
+static void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
+				    struct mlx5_core_dev *dev,
+				    u64 trace_timestamp)
+{
+	char	tmp[512];
+
+	snprintf(tmp, sizeof(tmp), str_frmt->string,
+		 str_frmt->params[0],
+		 str_frmt->params[1],
+		 str_frmt->params[2],
+		 str_frmt->params[3],
+		 str_frmt->params[4],
+		 str_frmt->params[5],
+		 str_frmt->params[6]);
+
+	trace_mlx5_fw(dev->tracer, trace_timestamp, str_frmt->lost,
+		      str_frmt->event_id, tmp);
+
+	/* remove it from hash */
+	mlx5_tracer_clean_message(str_frmt);
+}
+
+static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+					   struct tracer_event *tracer_event)
+{
+	struct tracer_string_format *cur_string;
+
+	if (tracer_event->string_event.tdsn == 0) {
+		cur_string = mlx5_tracer_get_string(tracer, tracer_event);
+		if (!cur_string)
+			return -1;
+
+		cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
+		cur_string->last_param_num = 0;
+		cur_string->event_id = tracer_event->event_id;
+		cur_string->tmsn = tracer_event->string_event.tmsn;
+		cur_string->timestamp = tracer_event->string_event.timestamp;
+		cur_string->lost = tracer_event->lost_event;
+		if (cur_string->num_of_params == 0) /* trace with no params */
+			list_add_tail(&cur_string->list, &tracer->ready_strings_list);
+	} else {
+		cur_string = mlx5_tracer_message_get(tracer, tracer_event);
+		if (!cur_string) {
+			pr_debug("%s Got string event for unknown string tdsm: %d\n",
+				 __func__, tracer_event->string_event.tmsn);
+			return -1;
+		}
+		cur_string->last_param_num += 1;
+		if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
+			pr_debug("%s Number of params exceeds the max (%d)\n",
+				 __func__, TRACER_MAX_PARAMS);
+			list_add_tail(&cur_string->list, &tracer->ready_strings_list);
+			return 0;
+		}
+		/* keep the new parameter */
+		cur_string->params[cur_string->last_param_num - 1] =
+			tracer_event->string_event.string_param;
+		if (cur_string->last_param_num == cur_string->num_of_params)
+			list_add_tail(&cur_string->list, &tracer->ready_strings_list);
+	}
+
+	return 0;
+}
+
+static void mlx5_tracer_handle_timestamp_trace(struct mlx5_fw_tracer *tracer,
+					       struct tracer_event *tracer_event)
+{
+	struct tracer_timestamp_event timestamp_event =
+						tracer_event->timestamp_event;
+	struct tracer_string_format *str_frmt, *tmp_str;
+	struct mlx5_core_dev *dev = tracer->dev;
+	u64 trace_timestamp;
+
+	list_for_each_entry_safe(str_frmt, tmp_str, &tracer->ready_strings_list, list) {
+		list_del(&str_frmt->list);
+		if (str_frmt->timestamp < (timestamp_event.timestamp & MASK_6_0))
+			trace_timestamp = (timestamp_event.timestamp & MASK_52_7) |
+					  (str_frmt->timestamp & MASK_6_0);
+		else
+			trace_timestamp = ((timestamp_event.timestamp & MASK_52_7) - 1) |
+					  (str_frmt->timestamp & MASK_6_0);
+
+		mlx5_tracer_print_trace(str_frmt, dev, trace_timestamp);
+	}
+}
+
+static int mlx5_tracer_handle_trace(struct mlx5_fw_tracer *tracer,
+				    struct tracer_event *tracer_event)
+{
+	if (tracer_event->type == TRACER_EVENT_TYPE_STRING) {
+		mlx5_tracer_handle_string_trace(tracer, tracer_event);
+	} else if (tracer_event->type == TRACER_EVENT_TYPE_TIMESTAMP) {
+		if (!tracer_event->timestamp_event.unreliable)
+			mlx5_tracer_handle_timestamp_trace(tracer, tracer_event);
+	} else {
+		pr_debug("%s Got unrecognised type %d for parsing, exiting..\n",
+			 __func__, tracer_event->type);
+	}
+	return 0;
+}
+
 static void mlx5_fw_tracer_handle_traces(struct work_struct *work)
 {
 	struct mlx5_fw_tracer *tracer =
@@ -452,8 +678,10 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work)
 		}
 
 		/* Parse events */
-		for (i = 0; i < TRACES_PER_BLOCK ; i++)
+		for (i = 0; i < TRACES_PER_BLOCK ; i++) {
 			poll_trace(tracer, &tracer_event, &tmp_trace_block[i]);
+			mlx5_tracer_handle_trace(tracer, &tracer_event);
+		}
 
 		tracer->buff.consumer_index =
 			(tracer->buff.consumer_index + 1) & (block_count - 1);
@@ -578,6 +806,7 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
 
 	tracer->dev = dev;
 
+	INIT_LIST_HEAD(&tracer->ready_strings_list);
 	INIT_WORK(&tracer->ownership_change_work, mlx5_fw_tracer_ownership_change);
 	INIT_WORK(&tracer->read_fw_strings_work, mlx5_tracer_read_strings_db);
 	INIT_WORK(&tracer->handle_traces_work, mlx5_fw_tracer_handle_traces);
@@ -675,6 +904,8 @@ void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer)
 		return;
 
 	cancel_work_sync(&tracer->read_fw_strings_work);
+	mlx5_fw_tracer_clean_ready_list(tracer);
+	mlx5_fw_tracer_clean_print_hash(tracer);
 	mlx5_fw_tracer_free_strings_db(tracer);
 	mlx5_fw_tracer_destroy_log_buf(tracer);
 	flush_workqueue(tracer->work_queue);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
index 3915e91486b2..8d310e7d6743 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
@@ -46,6 +46,13 @@
 #define TRACER_BLOCK_SIZE_BYTE 256
 #define TRACES_PER_BLOCK 32
 
+#define TRACER_MAX_PARAMS 7
+#define MESSAGE_HASH_BITS 6
+#define MESSAGE_HASH_SIZE BIT(MESSAGE_HASH_BITS)
+
+#define MASK_52_7 (0x1FFFFFFFFFFF80)
+#define MASK_6_0  (0x7F)
+
 struct mlx5_fw_tracer {
 	struct mlx5_core_dev *dev;
 	bool owner;
@@ -77,6 +84,21 @@ struct mlx5_fw_tracer {
 
 	u64 last_timestamp;
 	struct work_struct handle_traces_work;
+	struct hlist_head hash[MESSAGE_HASH_SIZE];
+	struct list_head ready_strings_list;
+};
+
+struct tracer_string_format {
+	char *string;
+	int params[TRACER_MAX_PARAMS];
+	int num_of_params;
+	int last_param_num;
+	u8 event_id;
+	u32 tmsn;
+	struct hlist_node hlist;
+	struct list_head list;
+	u32 timestamp;
+	bool lost;
 };
 
 enum mlx5_fw_tracer_ownership_state {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer_tracepoint.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer_tracepoint.h
new file mode 100644
index 000000000000..83f90e9aff45
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer_tracepoint.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#if !defined(__LIB_TRACER_TRACEPOINT_H__) || defined(TRACE_HEADER_MULTI_READ)
+#define __LIB_TRACER_TRACEPOINT_H__
+
+#include <linux/tracepoint.h>
+#include "fw_tracer.h"
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM mlx5
+
+/* Tracepoint for FWTracer messages: */
+TRACE_EVENT(mlx5_fw,
+	TP_PROTO(const struct mlx5_fw_tracer *tracer, u64 trace_timestamp,
+		 bool lost, u8 event_id, const char *msg),
+
+	TP_ARGS(tracer, trace_timestamp, lost, event_id, msg),
+
+	TP_STRUCT__entry(
+		__string(dev_name, dev_name(&tracer->dev->pdev->dev))
+		__field(u64, trace_timestamp)
+		__field(bool, lost)
+		__field(u8, event_id)
+		__string(msg, msg)
+	),
+
+	TP_fast_assign(
+		__assign_str(dev_name, dev_name(&tracer->dev->pdev->dev));
+		__entry->trace_timestamp = trace_timestamp;
+		__entry->lost = lost;
+		__entry->event_id = event_id;
+		__assign_str(msg, msg);
+	),
+
+	TP_printk("%s [0x%llx] %d [0x%x] %s",
+		  __get_str(dev_name),
+		  __entry->trace_timestamp,
+		  __entry->lost, __entry->event_id,
+		  __get_str(msg))
+);
+
+#endif
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH ./diag
+#define TRACE_INCLUDE_FILE fw_tracer_tracepoint
+#include <trace/define_trace.h>
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 02/12] net/mlx5: FW tracer, create trace buffer and copy strings database
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Feras Daoud, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

From: Feras Daoud <ferasda@mellanox.com>

For each PF do the following:
1- Allocate memory for the tracer strings database and read the
strings from the FW to the SW. These strings will be used later for
parsing traces.
2- Allocate and dma map tracer buffers.

Traces that will be written into the buffer will be parsed as a group
of one or more traces, referred to as trace message. The trace message
represents a C-like printf string.
First trace of a message holds the pointer to the correct string in
strings database. The following traces holds the variables of the
message.

Signed-off-by: Feras Daoud <ferasda@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../mellanox/mlx5/core/diag/fw_tracer.c       | 209 +++++++++++++++++-
 .../mellanox/mlx5/core/diag/fw_tracer.h       |  18 ++
 2 files changed, 224 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
index 3ecbf06b4d71..35107b8f76df 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
@@ -119,6 +119,163 @@ static void mlx5_fw_tracer_ownership_release(struct mlx5_fw_tracer *tracer)
 	tracer->owner = false;
 }
 
+static int mlx5_fw_tracer_create_log_buf(struct mlx5_fw_tracer *tracer)
+{
+	struct mlx5_core_dev *dev = tracer->dev;
+	struct device *ddev = &dev->pdev->dev;
+	dma_addr_t dma;
+	void *buff;
+	gfp_t gfp;
+	int err;
+
+	tracer->buff.size = TRACE_BUFFER_SIZE_BYTE;
+
+	gfp = GFP_KERNEL | __GFP_ZERO;
+	buff = (void *)__get_free_pages(gfp,
+					get_order(tracer->buff.size));
+	if (!buff) {
+		err = -ENOMEM;
+		mlx5_core_warn(dev, "FWTracer: Failed to allocate pages, %d\n", err);
+		return err;
+	}
+	tracer->buff.log_buf = buff;
+
+	dma = dma_map_single(ddev, buff, tracer->buff.size, DMA_FROM_DEVICE);
+	if (dma_mapping_error(ddev, dma)) {
+		mlx5_core_warn(dev, "FWTracer: Unable to map DMA: %d\n",
+			       dma_mapping_error(ddev, dma));
+		err = -ENOMEM;
+		goto free_pages;
+	}
+	tracer->buff.dma = dma;
+
+	return 0;
+
+free_pages:
+	free_pages((unsigned long)tracer->buff.log_buf, get_order(tracer->buff.size));
+
+	return err;
+}
+
+static void mlx5_fw_tracer_destroy_log_buf(struct mlx5_fw_tracer *tracer)
+{
+	struct mlx5_core_dev *dev = tracer->dev;
+	struct device *ddev = &dev->pdev->dev;
+
+	if (!tracer->buff.log_buf)
+		return;
+
+	dma_unmap_single(ddev, tracer->buff.dma, tracer->buff.size, DMA_FROM_DEVICE);
+	free_pages((unsigned long)tracer->buff.log_buf, get_order(tracer->buff.size));
+}
+
+static void mlx5_fw_tracer_free_strings_db(struct mlx5_fw_tracer *tracer)
+{
+	u32 num_string_db = tracer->str_db.num_string_db;
+	int i;
+
+	for (i = 0; i < num_string_db; i++) {
+		kfree(tracer->str_db.buffer[i]);
+		tracer->str_db.buffer[i] = NULL;
+	}
+}
+
+static int mlx5_fw_tracer_allocate_strings_db(struct mlx5_fw_tracer *tracer)
+{
+	u32 *string_db_size_out = tracer->str_db.size_out;
+	u32 num_string_db = tracer->str_db.num_string_db;
+	int i;
+
+	for (i = 0; i < num_string_db; i++) {
+		tracer->str_db.buffer[i] = kzalloc(string_db_size_out[i], GFP_KERNEL);
+		if (!tracer->str_db.buffer[i])
+			goto free_strings_db;
+	}
+
+	return 0;
+
+free_strings_db:
+	mlx5_fw_tracer_free_strings_db(tracer);
+	return -ENOMEM;
+}
+
+static void mlx5_tracer_read_strings_db(struct work_struct *work)
+{
+	struct mlx5_fw_tracer *tracer = container_of(work, struct mlx5_fw_tracer,
+						     read_fw_strings_work);
+	u32 num_of_reads, num_string_db = tracer->str_db.num_string_db;
+	struct mlx5_core_dev *dev = tracer->dev;
+	u32 in[MLX5_ST_SZ_DW(mtrc_cap)] = {0};
+	u32 leftovers, offset;
+	int err = 0, i, j;
+	u32 *out, outlen;
+	void *out_value;
+
+	outlen = MLX5_ST_SZ_BYTES(mtrc_stdb) + STRINGS_DB_READ_SIZE_BYTES;
+	out = kzalloc(outlen, GFP_KERNEL);
+	if (!out) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < num_string_db; i++) {
+		offset = 0;
+		MLX5_SET(mtrc_stdb, in, string_db_index, i);
+		num_of_reads = tracer->str_db.size_out[i] /
+				STRINGS_DB_READ_SIZE_BYTES;
+		leftovers = (tracer->str_db.size_out[i] %
+				STRINGS_DB_READ_SIZE_BYTES) /
+					STRINGS_DB_LEFTOVER_SIZE_BYTES;
+
+		MLX5_SET(mtrc_stdb, in, read_size, STRINGS_DB_READ_SIZE_BYTES);
+		for (j = 0; j < num_of_reads; j++) {
+			MLX5_SET(mtrc_stdb, in, start_offset, offset);
+
+			err = mlx5_core_access_reg(dev, in, sizeof(in), out,
+						   outlen, MLX5_REG_MTRC_STDB,
+						   0, 1);
+			if (err) {
+				mlx5_core_dbg(dev, "FWTracer: Failed to read strings DB %d\n",
+					      err);
+				goto out_free;
+			}
+
+			out_value = MLX5_ADDR_OF(mtrc_stdb, out, string_db_data);
+			memcpy(tracer->str_db.buffer[i] + offset, out_value,
+			       STRINGS_DB_READ_SIZE_BYTES);
+			offset += STRINGS_DB_READ_SIZE_BYTES;
+		}
+
+		/* Strings database is aligned to 64, need to read leftovers*/
+		MLX5_SET(mtrc_stdb, in, read_size,
+			 STRINGS_DB_LEFTOVER_SIZE_BYTES);
+		for (j = 0; j < leftovers; j++) {
+			MLX5_SET(mtrc_stdb, in, start_offset, offset);
+
+			err = mlx5_core_access_reg(dev, in, sizeof(in), out,
+						   outlen, MLX5_REG_MTRC_STDB,
+						   0, 1);
+			if (err) {
+				mlx5_core_dbg(dev, "FWTracer: Failed to read strings DB %d\n",
+					      err);
+				goto out_free;
+			}
+
+			out_value = MLX5_ADDR_OF(mtrc_stdb, out, string_db_data);
+			memcpy(tracer->str_db.buffer[i] + offset, out_value,
+			       STRINGS_DB_LEFTOVER_SIZE_BYTES);
+			offset += STRINGS_DB_LEFTOVER_SIZE_BYTES;
+		}
+	}
+
+	tracer->str_db.loaded = true;
+
+out_free:
+	kfree(out);
+out:
+	return;
+}
+
 static void mlx5_fw_tracer_ownership_change(struct work_struct *work)
 {
 	struct mlx5_fw_tracer *tracer = container_of(work, struct mlx5_fw_tracer,
@@ -161,6 +318,7 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
 	tracer->dev = dev;
 
 	INIT_WORK(&tracer->ownership_change_work, mlx5_fw_tracer_ownership_change);
+	INIT_WORK(&tracer->read_fw_strings_work, mlx5_tracer_read_strings_db);
 
 	err = mlx5_query_mtrc_caps(tracer);
 	if (err) {
@@ -168,10 +326,22 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
 		goto destroy_workqueue;
 	}
 
-	mlx5_fw_tracer_ownership_change(&tracer->ownership_change_work);
+	err = mlx5_fw_tracer_create_log_buf(tracer);
+	if (err) {
+		mlx5_core_warn(dev, "FWTracer: Create log buffer failed %d\n", err);
+		goto destroy_workqueue;
+	}
+
+	err = mlx5_fw_tracer_allocate_strings_db(tracer);
+	if (err) {
+		mlx5_core_warn(dev, "FWTracer: Allocate strings database failed %d\n", err);
+		goto free_log_buf;
+	}
 
 	return tracer;
 
+free_log_buf:
+	mlx5_fw_tracer_destroy_log_buf(tracer);
 destroy_workqueue:
 	tracer->dev = NULL;
 	destroy_workqueue(tracer->work_queue);
@@ -180,17 +350,50 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
 	return ERR_PTR(err);
 }
 
-void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer)
+int mlx5_fw_tracer_init(struct mlx5_fw_tracer *tracer)
 {
-	if (!tracer)
+	struct mlx5_core_dev *dev;
+	int err;
+
+	if (IS_ERR_OR_NULL(tracer))
+		return 0;
+
+	dev = tracer->dev;
+
+	if (!tracer->str_db.loaded)
+		queue_work(tracer->work_queue, &tracer->read_fw_strings_work);
+
+	err = mlx5_fw_tracer_ownership_acquire(tracer);
+	if (err) {
+		mlx5_core_dbg(dev, "FWTracer: Ownership was not granted %d\n", err);
+		return 0; /* return 0 since ownership can be acquired on a later FW event */
+	}
+
+	return 0;
+}
+
+void mlx5_fw_tracer_cleanup(struct mlx5_fw_tracer *tracer)
+{
+	if (IS_ERR_OR_NULL(tracer))
 		return;
 
 	cancel_work_sync(&tracer->ownership_change_work);
 
 	if (tracer->owner)
 		mlx5_fw_tracer_ownership_release(tracer);
+}
 
+void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer)
+{
+	if (IS_ERR_OR_NULL(tracer))
+		return;
+
+	cancel_work_sync(&tracer->read_fw_strings_work);
+	mlx5_fw_tracer_free_strings_db(tracer);
+	mlx5_fw_tracer_destroy_log_buf(tracer);
 	flush_workqueue(tracer->work_queue);
 	destroy_workqueue(tracer->work_queue);
 	kfree(tracer);
 }
+
+EXPORT_TRACEPOINT_SYMBOL(mlx5_fw);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
index 721c41a5e827..66cb7e7ada28 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
@@ -37,6 +37,11 @@
 #include "mlx5_core.h"
 
 #define STRINGS_DB_SECTIONS_NUM 8
+#define STRINGS_DB_READ_SIZE_BYTES 256
+#define STRINGS_DB_LEFTOVER_SIZE_BYTES 64
+#define TRACER_BUFFER_PAGE_NUM 64
+#define TRACER_BUFFER_CHUNK 4096
+#define TRACE_BUFFER_SIZE_BYTE (TRACER_BUFFER_PAGE_NUM * TRACER_BUFFER_CHUNK)
 
 struct mlx5_fw_tracer {
 	struct mlx5_core_dev *dev;
@@ -44,6 +49,7 @@ struct mlx5_fw_tracer {
 	u8   trc_ver;
 	struct workqueue_struct *work_queue;
 	struct work_struct ownership_change_work;
+	struct work_struct read_fw_strings_work;
 
 	/* Strings DB */
 	struct {
@@ -52,7 +58,19 @@ struct mlx5_fw_tracer {
 		u32 num_string_db;
 		u32 base_address_out[STRINGS_DB_SECTIONS_NUM];
 		u32 size_out[STRINGS_DB_SECTIONS_NUM];
+		void *buffer[STRINGS_DB_SECTIONS_NUM];
+		bool loaded;
 	} str_db;
+
+	/* Log Buffer */
+	struct {
+		u32 pdn;
+		void *log_buf;
+		dma_addr_t dma;
+		u32 size;
+		struct mlx5_core_mkey mkey;
+
+	} buff;
 };
 
 enum mlx5_fw_tracer_ownership_state {
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 03/12] net/mlx5: FW tracer, register log buffer memory key
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

Create a memory key and protection domain for the tracer log buffer.

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../mellanox/mlx5/core/diag/fw_tracer.c       | 64 ++++++++++++++++++-
 1 file changed, 61 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
index 35107b8f76df..d6cc27b0ff34 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
@@ -169,6 +169,48 @@ static void mlx5_fw_tracer_destroy_log_buf(struct mlx5_fw_tracer *tracer)
 	free_pages((unsigned long)tracer->buff.log_buf, get_order(tracer->buff.size));
 }
 
+static int mlx5_fw_tracer_create_mkey(struct mlx5_fw_tracer *tracer)
+{
+	struct mlx5_core_dev *dev = tracer->dev;
+	int err, inlen, i;
+	__be64 *mtt;
+	void *mkc;
+	u32 *in;
+
+	inlen = MLX5_ST_SZ_BYTES(create_mkey_in) +
+			sizeof(*mtt) * round_up(TRACER_BUFFER_PAGE_NUM, 2);
+
+	in = kvzalloc(inlen, GFP_KERNEL);
+	if (!in)
+		return -ENOMEM;
+
+	MLX5_SET(create_mkey_in, in, translations_octword_actual_size,
+		 DIV_ROUND_UP(TRACER_BUFFER_PAGE_NUM, 2));
+	mtt = (u64 *)MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt);
+	for (i = 0 ; i < TRACER_BUFFER_PAGE_NUM ; i++)
+		mtt[i] = cpu_to_be64(tracer->buff.dma + i * PAGE_SIZE);
+
+	mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
+	MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_MTT);
+	MLX5_SET(mkc, mkc, lr, 1);
+	MLX5_SET(mkc, mkc, lw, 1);
+	MLX5_SET(mkc, mkc, pd, tracer->buff.pdn);
+	MLX5_SET(mkc, mkc, bsf_octword_size, 0);
+	MLX5_SET(mkc, mkc, qpn, 0xffffff);
+	MLX5_SET(mkc, mkc, log_page_size, PAGE_SHIFT);
+	MLX5_SET(mkc, mkc, translations_octword_size,
+		 DIV_ROUND_UP(TRACER_BUFFER_PAGE_NUM, 2));
+	MLX5_SET64(mkc, mkc, start_addr, tracer->buff.dma);
+	MLX5_SET64(mkc, mkc, len, tracer->buff.size);
+	err = mlx5_core_create_mkey(dev, &tracer->buff.mkey, in, inlen);
+	if (err)
+		mlx5_core_warn(dev, "FWTracer: Failed to create mkey, %d\n", err);
+
+	kvfree(in);
+
+	return err;
+}
+
 static void mlx5_fw_tracer_free_strings_db(struct mlx5_fw_tracer *tracer)
 {
 	u32 num_string_db = tracer->str_db.num_string_db;
@@ -363,13 +405,26 @@ int mlx5_fw_tracer_init(struct mlx5_fw_tracer *tracer)
 	if (!tracer->str_db.loaded)
 		queue_work(tracer->work_queue, &tracer->read_fw_strings_work);
 
-	err = mlx5_fw_tracer_ownership_acquire(tracer);
+	err = mlx5_core_alloc_pd(dev, &tracer->buff.pdn);
 	if (err) {
-		mlx5_core_dbg(dev, "FWTracer: Ownership was not granted %d\n", err);
-		return 0; /* return 0 since ownership can be acquired on a later FW event */
+		mlx5_core_warn(dev, "FWTracer: Failed to allocate PD %d\n", err);
+		return err;
 	}
 
+	err = mlx5_fw_tracer_create_mkey(tracer);
+	if (err) {
+		mlx5_core_warn(dev, "FWTracer: Failed to create mkey %d\n", err);
+		goto err_dealloc_pd;
+	}
+
+	err = mlx5_fw_tracer_ownership_acquire(tracer);
+	if (err) /* Don't fail since ownership can be acquired on a later FW event */
+		mlx5_core_dbg(dev, "FWTracer: Ownership was not granted %d\n", err);
+
 	return 0;
+err_dealloc_pd:
+	mlx5_core_dealloc_pd(dev, tracer->buff.pdn);
+	return err;
 }
 
 void mlx5_fw_tracer_cleanup(struct mlx5_fw_tracer *tracer)
@@ -381,6 +436,9 @@ void mlx5_fw_tracer_cleanup(struct mlx5_fw_tracer *tracer)
 
 	if (tracer->owner)
 		mlx5_fw_tracer_ownership_release(tracer);
+
+	mlx5_core_destroy_mkey(tracer->dev, &tracer->buff.mkey);
+	mlx5_core_dealloc_pd(tracer->dev, tracer->buff.pdn);
 }
 
 void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer)
-- 
2.17.0

^ permalink raw reply related

* [net-next V2 01/12] net/mlx5: FW tracer, implement tracer logic
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Feras Daoud, Saeed Mahameed
In-Reply-To: <20180723221129.21625-1-saeedm@mellanox.com>

From: Feras Daoud <ferasda@mellanox.com>

Implement FW tracer logic and registers access, initialization and
cleanup flows.

Initializing the tracer will be part of load one flow, as multiple
PFs will try to acquire ownership but only one will succeed and will
be the tracer owner.

Signed-off-by: Feras Daoud <ferasda@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 .../mellanox/mlx5/core/diag/fw_tracer.c       | 196 ++++++++++++++++++
 .../mellanox/mlx5/core/diag/fw_tracer.h       |  66 ++++++
 include/linux/mlx5/driver.h                   |   3 +
 3 files changed, 265 insertions(+)
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
new file mode 100644
index 000000000000..3ecbf06b4d71
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2018, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "fw_tracer.h"
+
+static int mlx5_query_mtrc_caps(struct mlx5_fw_tracer *tracer)
+{
+	u32 *string_db_base_address_out = tracer->str_db.base_address_out;
+	u32 *string_db_size_out = tracer->str_db.size_out;
+	struct mlx5_core_dev *dev = tracer->dev;
+	u32 out[MLX5_ST_SZ_DW(mtrc_cap)] = {0};
+	u32 in[MLX5_ST_SZ_DW(mtrc_cap)] = {0};
+	void *mtrc_cap_sp;
+	int err, i;
+
+	err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
+				   MLX5_REG_MTRC_CAP, 0, 0);
+	if (err) {
+		mlx5_core_warn(dev, "FWTracer: Error reading tracer caps %d\n",
+			       err);
+		return err;
+	}
+
+	if (!MLX5_GET(mtrc_cap, out, trace_to_memory)) {
+		mlx5_core_dbg(dev, "FWTracer: Device does not support logging traces to memory\n");
+		return -ENOTSUPP;
+	}
+
+	tracer->trc_ver = MLX5_GET(mtrc_cap, out, trc_ver);
+	tracer->str_db.first_string_trace =
+			MLX5_GET(mtrc_cap, out, first_string_trace);
+	tracer->str_db.num_string_trace =
+			MLX5_GET(mtrc_cap, out, num_string_trace);
+	tracer->str_db.num_string_db = MLX5_GET(mtrc_cap, out, num_string_db);
+	tracer->owner = !!MLX5_GET(mtrc_cap, out, trace_owner);
+
+	for (i = 0; i < tracer->str_db.num_string_db; i++) {
+		mtrc_cap_sp = MLX5_ADDR_OF(mtrc_cap, out, string_db_param[i]);
+		string_db_base_address_out[i] = MLX5_GET(mtrc_string_db_param,
+							 mtrc_cap_sp,
+							 string_db_base_address);
+		string_db_size_out[i] = MLX5_GET(mtrc_string_db_param,
+						 mtrc_cap_sp, string_db_size);
+	}
+
+	return err;
+}
+
+static int mlx5_set_mtrc_caps_trace_owner(struct mlx5_fw_tracer *tracer,
+					  u32 *out, u32 out_size,
+					  u8 trace_owner)
+{
+	struct mlx5_core_dev *dev = tracer->dev;
+	u32 in[MLX5_ST_SZ_DW(mtrc_cap)] = {0};
+
+	MLX5_SET(mtrc_cap, in, trace_owner, trace_owner);
+
+	return mlx5_core_access_reg(dev, in, sizeof(in), out, out_size,
+				    MLX5_REG_MTRC_CAP, 0, 1);
+}
+
+static int mlx5_fw_tracer_ownership_acquire(struct mlx5_fw_tracer *tracer)
+{
+	struct mlx5_core_dev *dev = tracer->dev;
+	u32 out[MLX5_ST_SZ_DW(mtrc_cap)] = {0};
+	int err;
+
+	err = mlx5_set_mtrc_caps_trace_owner(tracer, out, sizeof(out),
+					     MLX5_FW_TRACER_ACQUIRE_OWNERSHIP);
+	if (err) {
+		mlx5_core_warn(dev, "FWTracer: Acquire tracer ownership failed %d\n",
+			       err);
+		return err;
+	}
+
+	tracer->owner = !!MLX5_GET(mtrc_cap, out, trace_owner);
+
+	if (!tracer->owner)
+		return -EBUSY;
+
+	return 0;
+}
+
+static void mlx5_fw_tracer_ownership_release(struct mlx5_fw_tracer *tracer)
+{
+	u32 out[MLX5_ST_SZ_DW(mtrc_cap)] = {0};
+
+	mlx5_set_mtrc_caps_trace_owner(tracer, out, sizeof(out),
+				       MLX5_FW_TRACER_RELEASE_OWNERSHIP);
+	tracer->owner = false;
+}
+
+static void mlx5_fw_tracer_ownership_change(struct work_struct *work)
+{
+	struct mlx5_fw_tracer *tracer = container_of(work, struct mlx5_fw_tracer,
+						     ownership_change_work);
+	struct mlx5_core_dev *dev = tracer->dev;
+	int err;
+
+	if (tracer->owner) {
+		mlx5_fw_tracer_ownership_release(tracer);
+		return;
+	}
+
+	err = mlx5_fw_tracer_ownership_acquire(tracer);
+	if (err) {
+		mlx5_core_dbg(dev, "FWTracer: Ownership was not granted %d\n", err);
+		return;
+	}
+}
+
+struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
+{
+	struct mlx5_fw_tracer *tracer = NULL;
+	int err;
+
+	if (!MLX5_CAP_MCAM_REG(dev, tracer_registers)) {
+		mlx5_core_dbg(dev, "FWTracer: Tracer capability not present\n");
+		return NULL;
+	}
+
+	tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
+	if (!tracer)
+		return ERR_PTR(-ENOMEM);
+
+	tracer->work_queue = create_singlethread_workqueue("mlx5_fw_tracer");
+	if (!tracer->work_queue) {
+		err = -ENOMEM;
+		goto free_tracer;
+	}
+
+	tracer->dev = dev;
+
+	INIT_WORK(&tracer->ownership_change_work, mlx5_fw_tracer_ownership_change);
+
+	err = mlx5_query_mtrc_caps(tracer);
+	if (err) {
+		mlx5_core_dbg(dev, "FWTracer: Failed to query capabilities %d\n", err);
+		goto destroy_workqueue;
+	}
+
+	mlx5_fw_tracer_ownership_change(&tracer->ownership_change_work);
+
+	return tracer;
+
+destroy_workqueue:
+	tracer->dev = NULL;
+	destroy_workqueue(tracer->work_queue);
+free_tracer:
+	kfree(tracer);
+	return ERR_PTR(err);
+}
+
+void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer)
+{
+	if (!tracer)
+		return;
+
+	cancel_work_sync(&tracer->ownership_change_work);
+
+	if (tracer->owner)
+		mlx5_fw_tracer_ownership_release(tracer);
+
+	flush_workqueue(tracer->work_queue);
+	destroy_workqueue(tracer->work_queue);
+	kfree(tracer);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
new file mode 100644
index 000000000000..721c41a5e827
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __LIB_TRACER_H__
+#define __LIB_TRACER_H__
+
+#include <linux/mlx5/driver.h>
+#include "mlx5_core.h"
+
+#define STRINGS_DB_SECTIONS_NUM 8
+
+struct mlx5_fw_tracer {
+	struct mlx5_core_dev *dev;
+	bool owner;
+	u8   trc_ver;
+	struct workqueue_struct *work_queue;
+	struct work_struct ownership_change_work;
+
+	/* Strings DB */
+	struct {
+		u8 first_string_trace;
+		u8 num_string_trace;
+		u32 num_string_db;
+		u32 base_address_out[STRINGS_DB_SECTIONS_NUM];
+		u32 size_out[STRINGS_DB_SECTIONS_NUM];
+	} str_db;
+};
+
+enum mlx5_fw_tracer_ownership_state {
+	MLX5_FW_TRACER_RELEASE_OWNERSHIP,
+	MLX5_FW_TRACER_ACQUIRE_OWNERSHIP,
+};
+
+struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev);
+void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer);
+
+#endif
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 957199c20a0f..86cb0ebf92fa 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -816,6 +816,8 @@ struct mlx5_clock {
 	struct mlx5_pps            pps_info;
 };
 
+struct mlx5_fw_tracer;
+
 struct mlx5_core_dev {
 	struct pci_dev	       *pdev;
 	/* sync pci state */
@@ -860,6 +862,7 @@ struct mlx5_core_dev {
 	struct mlx5_clock        clock;
 	struct mlx5_ib_clock_info  *clock_info;
 	struct page             *clock_info_page;
+	struct mlx5_fw_tracer   *tracer;
 };
 
 struct mlx5_db {
-- 
2.17.0

^ permalink raw reply related

* [pull request][net-next V2 00/12] Mellanox, mlx5e updates 2018-07-18
From: Saeed Mahameed @ 2018-07-23 22:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Saeed Mahameed

Hi Dave,

This series includes updates for mlx5e net device driver, with a couple
of major features and some misc updates.

Please notice the mlx5-next merge patch at the beginning:
"Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux"

For more information please see tag log below.

Please pull and let me know if there's any problem.

v1->v2:
- Dropped "Support PCIe buffer congestion handling via Devlink" patches until the
comments are addressed.

Thanks,
Saeed.

---

The following changes since commit 7854ac44fe86548f8a6c6001938a1a2593b255e4:

  Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux (2018-07-23 14:58:46 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux.git tags/mlx5e-updates-2018-07-18-v2

for you to fetch changes up to 3f44899ef2ce0c9da49feb0d6f08098a08cb96ae:

  net/mlx5e: Use PARTIAL_GSO for UDP segmentation (2018-07-23 15:01:11 -0700)

----------------------------------------------------------------
mlx5e-updates-2018-07-18

This series includes update for mlx5e net device driver.

1) From Feras Daoud, Added the support for firmware log tracing,
first by introducing the firmware API needed for the task and then
For each PF do the following:
    1- Allocate memory for the tracer strings database and read it from the FW to the SW.
    2- Allocate and dma map tracer buffers.

    Traces that will be written into the buffer will be parsed as a group
    of one or more traces, referred to as trace message. The trace message
    represents a C-like printf string.
Once a new trace is available  FW will generate an event indicates new trace/s are
available and the driver will parse them and dump them using tracepoints
event tracing

Enable mlx5 fw tracing by:
echo 1 > /sys/kernel/debug/tracing/events/mlx5/mlx5_fw/enable

Read traces by:
cat /sys/kernel/debug/tracing/trace

2) From Roi Dayan, Remove redundant WARN when we cannot find neigh entry

3) From Jianbo Liu, TC double vlan support
- Support offloading tc double vlan headers match
- Support offloading double vlan push/pop tc actions

4) From Boris, re-visit UDP GSO, remove the splitting of UDP_GSO_L4 packets
in the driver, and exposes UDP_GSO_L4 as a PARTIAL_GSO feature.

----------------------------------------------------------------
Boris Pismenny (1):
      net/mlx5e: Use PARTIAL_GSO for UDP segmentation

Feras Daoud (5):
      net/mlx5: FW tracer, implement tracer logic
      net/mlx5: FW tracer, create trace buffer and copy strings database
      net/mlx5: FW tracer, events handling
      net/mlx5: FW tracer, parse traces and kernel tracing support
      net/mlx5: FW tracer, Enable tracing

Jianbo Liu (3):
      net/mlx5e: Support offloading tc double vlan headers match
      net/mlx5e: Refactor tc vlan push/pop actions offloading
      net/mlx5e: Support offloading double vlan push/pop tc actions

Roi Dayan (1):
      net/mlx5e: Remove redundant WARN when we cannot find neigh entry

Saeed Mahameed (2):
      net/mlx5: FW tracer, register log buffer memory key
      net/mlx5: FW tracer, Add debug prints

 drivers/net/ethernet/mellanox/mlx5/core/Makefile   |   6 +-
 .../ethernet/mellanox/mlx5/core/diag/fw_tracer.c   | 947 +++++++++++++++++++++
 .../ethernet/mellanox/mlx5/core/diag/fw_tracer.h   | 175 ++++
 .../mellanox/mlx5/core/diag/fw_tracer_tracepoint.h |  78 ++
 .../mellanox/mlx5/core/en_accel/en_accel.h         |  27 +-
 .../ethernet/mellanox/mlx5/core/en_accel/rxtx.c    | 109 ---
 .../ethernet/mellanox/mlx5/core/en_accel/rxtx.h    |  14 -
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |   9 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c    | 134 ++-
 drivers/net/ethernet/mellanox/mlx5/core/eq.c       |  11 +
 drivers/net/ethernet/mellanox/mlx5/core/eswitch.h  |  21 +-
 .../ethernet/mellanox/mlx5/core/eswitch_offloads.c |  23 +-
 drivers/net/ethernet/mellanox/mlx5/core/main.c     |  18 +-
 include/linux/mlx5/device.h                        |   7 +
 include/linux/mlx5/driver.h                        |   3 +
 15 files changed, 1399 insertions(+), 183 deletions(-)
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer_tracepoint.h
 delete mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_accel/rxtx.c
 delete mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_accel/rxtx.h

^ permalink raw reply

* ✓ Fi.CI.IGT: success for series starting with [1/2] drm/dp: add extended receiver capability field present bit
From: Patchwork @ 2018-07-23 23:14 UTC (permalink / raw)
  To: matthew.s.atwood; +Cc: intel-gfx
In-Reply-To: <20180723212735.23893-1-matthew.s.atwood@intel.com>

== Series Details ==

Series: series starting with [1/2] drm/dp: add extended receiver capability field present bit
URL   : https://patchwork.freedesktop.org/series/47087/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_4530_full -> Patchwork_9753_full =

== Summary - WARNING ==

  Minor unknown changes coming with Patchwork_9753_full need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_9753_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

== Possible new issues ==

  Here are the unknown changes that may have been introduced in Patchwork_9753_full:

  === IGT changes ===

    ==== Warnings ====

    igt@gem_exec_schedule@deep-bsd2:
      shard-kbl:          PASS -> SKIP +1

    
== Known issues ==

  Here are the changes found in Patchwork_9753_full that come from known issues:

  === IGT changes ===

    ==== Issues hit ====

    igt@kms_flip@plain-flip-fb-recreate:
      shard-hsw:          PASS -> FAIL (fdo#100368)

    
    ==== Possible fixes ====

    igt@kms_flip@2x-dpms-vs-vblank-race-interruptible:
      shard-hsw:          FAIL (fdo#103060) -> PASS

    igt@kms_flip@2x-flip-vs-wf_vblank:
      shard-glk:          FAIL (fdo#100368) -> PASS

    igt@perf_pmu@rc6-runtime-pm-long:
      shard-kbl:          FAIL (fdo#105010) -> PASS

    
  fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368
  fdo#103060 https://bugs.freedesktop.org/show_bug.cgi?id=103060
  fdo#105010 https://bugs.freedesktop.org/show_bug.cgi?id=105010


== Participating hosts (5 -> 5) ==

  No changes in participating hosts


== Build changes ==

    * Linux: CI_DRM_4530 -> Patchwork_9753

  CI_DRM_4530: d27cc4a37a5cc1ef14a3aafdcb6682e5f6a85d09 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4571: 65fccc149b85968cdce4737266b056059c1510f3 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_9753: 23a1b794202633961ad336e9f57c1ba6cb184d93 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_9753/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply

* Re: [PATCH] drivers/pci/probe: Move variable bridge inside ifdef
From: Bjorn Helgaas @ 2018-07-23 22:11 UTC (permalink / raw)
  To: Anders Roxell; +Cc: bhelgaas, linux-pci, linux-kernel
In-Reply-To: <20180721214556.25651-1-anders.roxell@linaro.org>

On Sat, Jul 21, 2018 at 11:45:56PM +0200, Anders Roxell wrote:
> When CONFIG_PCI_QUIRKS isn't enabled we get the warning below:
> drivers/pci/probe.c: In function ‘pci_bus_read_dev_vendor_id’:
> drivers/pci/probe.c:2221:18: warning: unused variable ‘bridge’ [-Wunused-variable]
>   struct pci_dev *bridge = bus->self;
>                   ^~~~~~
> 
> Move the declaration of variable bridge to inside the ifdef
> CONFIG_PCI_QUIRKS.
> 
> Fixes: ac5ea104a279 ("PCI: Workaround IDT switch ACS Source Validation erratum")
> Signed-off-by: Anders Roxell <anders.roxell@linaro.org>

I folded this into the original commit on pci/enumeration, thanks!

> ---
>  drivers/pci/probe.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 1c581346c5b9..7a5323798312 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -2218,9 +2218,9 @@ bool pci_bus_generic_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
>  bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
>  				int timeout)
>  {
> +#ifdef CONFIG_PCI_QUIRKS
>  	struct pci_dev *bridge = bus->self;
>  
> -#ifdef CONFIG_PCI_QUIRKS
>  	/*
>  	 * Certain IDT switches have an issue where they improperly trigger
>  	 * ACS Source Validation errors on completions for config reads.
> -- 
> 2.18.0
> 

^ permalink raw reply


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