* Re: [PATCH v3 17/17] kasan: add SPDX-License-Identifier mark to source files
From: Fabio Estevam @ 2018-06-20 19:43 UTC (permalink / raw)
To: Andrey Konovalov
Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
Catalin Marinas, Will Deacon, Christoph Lameter, Andrew Morton,
Mark Rutland, Nick Desaulniers, Marc Zyngier, Dave Martin,
Ard Biesheuvel, Eric W . Biederman, Ingo Molnar, Paul Lawrence,
Geert Uytterhoeven, Arnd Bergmann, Kirill A . Shutemov,
Greg Kroah-Hartman, Kate Stewart, Mike Rapoport, kasan-dev,
linux-doc, linux-kernel,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
linux-sparse, Linux Memory Management List,
Linux Kbuild mailing list, Chintan Pandya, Jacob Bramley,
Jann Horn, Ruben Ayrapetyan, Lee Smith, Kostya Serebryany,
Mark Brand, Ramana Radhakrishnan, Evgeniy Stepanov
In-Reply-To: <CAAeHK+zJgSAxiHHfzhrm7N7iey7CbW42WfWvUN+FnZMPP3FXrA@mail.gmail.com>
On Wed, Jun 20, 2018 at 4:41 PM, Andrey Konovalov <andreyknvl@google.com> wrote:
> I used mm/slub.c as a reference, which uses //. Bu I can change it to
> /* */ in the next version, no problem.
C source files should use //. C header files should use /* */
This is documented at Documentation/process/license-rules.rst
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 02/17] khwasan: move common kasan and khwasan code to common.c
From: kbuild test robot @ 2018-06-20 20:36 UTC (permalink / raw)
To: Andrey Konovalov
Cc: kbuild-all, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
Catalin Marinas, Will Deacon, Christoph Lameter, Andrew Morton,
Mark Rutland, Nick Desaulniers, Marc Zyngier, Dave Martin,
Ard Biesheuvel, Eric W . Biederman, Ingo Molnar, Paul Lawrence,
Geert Uytterhoeven, Arnd Bergmann, Kirill A . Shutemov,
Greg Kroah-Hartman, Kate Stewart, Mike Rapoport, kasan-dev,
linux-doc, linux-kernel, linux-arm-kernel, linux-sparse, linux-mm,
linux-kbuild, Kostya Serebryany, Evgeniy Stepanov, Lee Smith,
Ramana Radhakrishnan, Jacob Bramley, Ruben Ayrapetyan, Jann Horn,
Mark Brand, Chintan Pandya, Andrey Konovalov
In-Reply-To: <687f2c3ce27015abb6bc412646894ae40051d8af.1529515183.git.andreyknvl@google.com>
[-- Attachment #1: Type: text/plain, Size: 9683 bytes --]
Hi Andrey,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on mmotm/master]
[also build test ERROR on v4.18-rc1 next-20180620]
[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/Andrey-Konovalov/khwasan-kernel-hardware-assisted-address-sanitizer/20180621-035912
base: git://git.cmpxchg.org/linux-mmotm.git master
config: x86_64-randconfig-x011-201824 (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=x86_64
Note: the linux-review/Andrey-Konovalov/khwasan-kernel-hardware-assisted-address-sanitizer/20180621-035912 HEAD 0e30ed7118e854b38bb6ab96365e7c74a2518290 builds fine.
It only hurts bisectibility.
All errors (new ones prefixed by >>):
>> mm//kasan/report.c:42:20: error: conflicting types for 'find_first_bad_addr'
static const void *find_first_bad_addr(const void *addr, size_t size)
^~~~~~~~~~~~~~~~~~~
In file included from mm//kasan/report.c:33:0:
mm//kasan/kasan.h:130:7: note: previous declaration of 'find_first_bad_addr' was here
void *find_first_bad_addr(void *addr, size_t size);
^~~~~~~~~~~~~~~~~~~
>> mm//kasan/report.c:54:13: error: conflicting types for 'addr_has_shadow'
static bool addr_has_shadow(struct kasan_access_info *info)
^~~~~~~~~~~~~~~
In file included from mm//kasan/report.c:33:0:
mm//kasan/kasan.h:120:20: note: previous definition of 'addr_has_shadow' was here
static inline bool addr_has_shadow(const void *addr)
^~~~~~~~~~~~~~~
mm//kasan/report.c: In function 'get_shadow_bug_type':
mm//kasan/report.c:86:2: error: duplicate case value
case KASAN_KMALLOC_REDZONE:
^~~~
mm//kasan/report.c:85:2: note: previously used here
case KASAN_PAGE_REDZONE:
^~~~
mm//kasan/report.c:98:2: error: duplicate case value
case KASAN_FREE_PAGE:
^~~~
mm//kasan/report.c:85:2: note: previously used here
case KASAN_PAGE_REDZONE:
^~~~
mm//kasan/report.c:99:2: error: duplicate case value
case KASAN_KMALLOC_FREE:
^~~~
mm//kasan/report.c:85:2: note: previously used here
case KASAN_PAGE_REDZONE:
^~~~
mm//kasan/report.c: At top level:
>> mm//kasan/report.c:128:20: error: static declaration of 'get_bug_type' follows non-static declaration
static const char *get_bug_type(struct kasan_access_info *info)
^~~~~~~~~~~~
In file included from mm//kasan/report.c:33:0:
mm//kasan/kasan.h:131:13: note: previous declaration of 'get_bug_type' was here
const char *get_bug_type(struct kasan_access_info *info);
^~~~~~~~~~~~
vim +/find_first_bad_addr +42 mm//kasan/report.c
0b24becc Andrey Ryabinin 2015-02-13 41
0b24becc Andrey Ryabinin 2015-02-13 @42 static const void *find_first_bad_addr(const void *addr, size_t size)
0b24becc Andrey Ryabinin 2015-02-13 43 {
0b24becc Andrey Ryabinin 2015-02-13 44 u8 shadow_val = *(u8 *)kasan_mem_to_shadow(addr);
0b24becc Andrey Ryabinin 2015-02-13 45 const void *first_bad_addr = addr;
0b24becc Andrey Ryabinin 2015-02-13 46
0b24becc Andrey Ryabinin 2015-02-13 47 while (!shadow_val && first_bad_addr < addr + size) {
0b24becc Andrey Ryabinin 2015-02-13 48 first_bad_addr += KASAN_SHADOW_SCALE_SIZE;
0b24becc Andrey Ryabinin 2015-02-13 49 shadow_val = *(u8 *)kasan_mem_to_shadow(first_bad_addr);
0b24becc Andrey Ryabinin 2015-02-13 50 }
0b24becc Andrey Ryabinin 2015-02-13 51 return first_bad_addr;
0b24becc Andrey Ryabinin 2015-02-13 52 }
0b24becc Andrey Ryabinin 2015-02-13 53
5e82cd12 Andrey Konovalov 2017-05-03 @54 static bool addr_has_shadow(struct kasan_access_info *info)
5e82cd12 Andrey Konovalov 2017-05-03 55 {
5e82cd12 Andrey Konovalov 2017-05-03 56 return (info->access_addr >=
5e82cd12 Andrey Konovalov 2017-05-03 57 kasan_shadow_to_mem((void *)KASAN_SHADOW_START));
5e82cd12 Andrey Konovalov 2017-05-03 58 }
5e82cd12 Andrey Konovalov 2017-05-03 59
5e82cd12 Andrey Konovalov 2017-05-03 60 static const char *get_shadow_bug_type(struct kasan_access_info *info)
0b24becc Andrey Ryabinin 2015-02-13 61 {
0952d87f Andrey Konovalov 2015-11-05 62 const char *bug_type = "unknown-crash";
cdf6a273 Andrey Konovalov 2015-11-05 63 u8 *shadow_addr;
0b24becc Andrey Ryabinin 2015-02-13 64
0b24becc Andrey Ryabinin 2015-02-13 65 info->first_bad_addr = find_first_bad_addr(info->access_addr,
0b24becc Andrey Ryabinin 2015-02-13 66 info->access_size);
0b24becc Andrey Ryabinin 2015-02-13 67
cdf6a273 Andrey Konovalov 2015-11-05 68 shadow_addr = (u8 *)kasan_mem_to_shadow(info->first_bad_addr);
0b24becc Andrey Ryabinin 2015-02-13 69
cdf6a273 Andrey Konovalov 2015-11-05 70 /*
cdf6a273 Andrey Konovalov 2015-11-05 71 * If shadow byte value is in [0, KASAN_SHADOW_SCALE_SIZE) we can look
cdf6a273 Andrey Konovalov 2015-11-05 72 * at the next shadow byte to determine the type of the bad access.
cdf6a273 Andrey Konovalov 2015-11-05 73 */
cdf6a273 Andrey Konovalov 2015-11-05 74 if (*shadow_addr > 0 && *shadow_addr <= KASAN_SHADOW_SCALE_SIZE - 1)
cdf6a273 Andrey Konovalov 2015-11-05 75 shadow_addr++;
cdf6a273 Andrey Konovalov 2015-11-05 76
cdf6a273 Andrey Konovalov 2015-11-05 77 switch (*shadow_addr) {
0952d87f Andrey Konovalov 2015-11-05 78 case 0 ... KASAN_SHADOW_SCALE_SIZE - 1:
cdf6a273 Andrey Konovalov 2015-11-05 79 /*
cdf6a273 Andrey Konovalov 2015-11-05 80 * In theory it's still possible to see these shadow values
cdf6a273 Andrey Konovalov 2015-11-05 81 * due to a data race in the kernel code.
cdf6a273 Andrey Konovalov 2015-11-05 82 */
0952d87f Andrey Konovalov 2015-11-05 83 bug_type = "out-of-bounds";
b8c73fc2 Andrey Ryabinin 2015-02-13 84 break;
0316bec2 Andrey Ryabinin 2015-02-13 85 case KASAN_PAGE_REDZONE:
0316bec2 Andrey Ryabinin 2015-02-13 86 case KASAN_KMALLOC_REDZONE:
0952d87f Andrey Konovalov 2015-11-05 87 bug_type = "slab-out-of-bounds";
0952d87f Andrey Konovalov 2015-11-05 88 break;
bebf56a1 Andrey Ryabinin 2015-02-13 89 case KASAN_GLOBAL_REDZONE:
0952d87f Andrey Konovalov 2015-11-05 90 bug_type = "global-out-of-bounds";
0b24becc Andrey Ryabinin 2015-02-13 91 break;
c420f167 Andrey Ryabinin 2015-02-13 92 case KASAN_STACK_LEFT:
c420f167 Andrey Ryabinin 2015-02-13 93 case KASAN_STACK_MID:
c420f167 Andrey Ryabinin 2015-02-13 94 case KASAN_STACK_RIGHT:
c420f167 Andrey Ryabinin 2015-02-13 95 case KASAN_STACK_PARTIAL:
0952d87f Andrey Konovalov 2015-11-05 96 bug_type = "stack-out-of-bounds";
0952d87f Andrey Konovalov 2015-11-05 97 break;
0952d87f Andrey Konovalov 2015-11-05 98 case KASAN_FREE_PAGE:
0952d87f Andrey Konovalov 2015-11-05 @99 case KASAN_KMALLOC_FREE:
0952d87f Andrey Konovalov 2015-11-05 100 bug_type = "use-after-free";
c420f167 Andrey Ryabinin 2015-02-13 101 break;
828347f8 Dmitry Vyukov 2016-11-30 102 case KASAN_USE_AFTER_SCOPE:
828347f8 Dmitry Vyukov 2016-11-30 103 bug_type = "use-after-scope";
828347f8 Dmitry Vyukov 2016-11-30 104 break;
342061ee Paul Lawrence 2018-02-06 105 case KASAN_ALLOCA_LEFT:
342061ee Paul Lawrence 2018-02-06 106 case KASAN_ALLOCA_RIGHT:
342061ee Paul Lawrence 2018-02-06 107 bug_type = "alloca-out-of-bounds";
342061ee Paul Lawrence 2018-02-06 108 break;
0b24becc Andrey Ryabinin 2015-02-13 109 }
0b24becc Andrey Ryabinin 2015-02-13 110
5e82cd12 Andrey Konovalov 2017-05-03 111 return bug_type;
5e82cd12 Andrey Konovalov 2017-05-03 112 }
5e82cd12 Andrey Konovalov 2017-05-03 113
822d5ec2 Colin Ian King 2017-07-10 114 static const char *get_wild_bug_type(struct kasan_access_info *info)
5e82cd12 Andrey Konovalov 2017-05-03 115 {
5e82cd12 Andrey Konovalov 2017-05-03 116 const char *bug_type = "unknown-crash";
5e82cd12 Andrey Konovalov 2017-05-03 117
5e82cd12 Andrey Konovalov 2017-05-03 118 if ((unsigned long)info->access_addr < PAGE_SIZE)
5e82cd12 Andrey Konovalov 2017-05-03 119 bug_type = "null-ptr-deref";
5e82cd12 Andrey Konovalov 2017-05-03 120 else if ((unsigned long)info->access_addr < TASK_SIZE)
5e82cd12 Andrey Konovalov 2017-05-03 121 bug_type = "user-memory-access";
5e82cd12 Andrey Konovalov 2017-05-03 122 else
5e82cd12 Andrey Konovalov 2017-05-03 123 bug_type = "wild-memory-access";
5e82cd12 Andrey Konovalov 2017-05-03 124
5e82cd12 Andrey Konovalov 2017-05-03 125 return bug_type;
5e82cd12 Andrey Konovalov 2017-05-03 126 }
5e82cd12 Andrey Konovalov 2017-05-03 127
7d418f7b Andrey Konovalov 2017-05-03 @128 static const char *get_bug_type(struct kasan_access_info *info)
7d418f7b Andrey Konovalov 2017-05-03 129 {
7d418f7b Andrey Konovalov 2017-05-03 130 if (addr_has_shadow(info))
7d418f7b Andrey Konovalov 2017-05-03 131 return get_shadow_bug_type(info);
7d418f7b Andrey Konovalov 2017-05-03 132 return get_wild_bug_type(info);
7d418f7b Andrey Konovalov 2017-05-03 133 }
7d418f7b Andrey Konovalov 2017-05-03 134
:::::: The code at line 42 was first introduced by commit
:::::: 0b24becc810dc3be6e3f94103a866f214c282394 kasan: add kernel address sanitizer infrastructure
:::::: TO: Andrey Ryabinin <a.ryabinin@samsung.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>
---
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: 35183 bytes --]
^ permalink raw reply
* Re: [PATCH v5 08/11] pci-epf-test/pci_endpoint_test: Add MSI-X support
From: kbuild test robot @ 2018-06-20 22:43 UTC (permalink / raw)
To: Gustavo Pimentel
Cc: kbuild-all, bhelgaas, lorenzo.pieralisi, Joao.Pinto, jingoohan1,
kishon, adouglas, jesper.nilsson, sboyd, linux-pci, linux-doc,
linux-kernel, Gustavo Pimentel
In-Reply-To: <75017264b560112aba5d631254f319961737fe7d.1529507416.git.gustavo.pimentel@synopsys.com>
[-- Attachment #1: Type: text/plain, Size: 2598 bytes --]
Hi Gustavo,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on pci/next]
[also build test ERROR on v4.18-rc1 next-20180620]
[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/Gustavo-Pimentel/Add-MSI-X-support-on-pcitest-tool/20180621-042813
base: https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: i386-randconfig-x000-201824 (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
Note: the linux-review/Gustavo-Pimentel/Add-MSI-X-support-on-pcitest-tool/20180621-042813 HEAD 049a341869c0b8bb5160581848bcbd6d077829e0 builds fine.
It only hurts bisectibility.
All errors (new ones prefixed by >>):
drivers//misc/pci_endpoint_test.c: In function 'pci_endpoint_test_ioctl':
>> drivers//misc/pci_endpoint_test.c:462:7: error: 'PCITEST_MSIX' undeclared (first use in this function); did you mean 'PCITEST_MSI'?
case PCITEST_MSIX:
^~~~~~~~~~~~
PCITEST_MSI
drivers//misc/pci_endpoint_test.c:462:7: note: each undeclared identifier is reported only once for each function it appears in
vim +462 drivers//misc/pci_endpoint_test.c
442
443 static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
444 unsigned long arg)
445 {
446 int ret = -EINVAL;
447 enum pci_barno bar;
448 struct pci_endpoint_test *test = to_endpoint_test(file->private_data);
449
450 mutex_lock(&test->mutex);
451 switch (cmd) {
452 case PCITEST_BAR:
453 bar = arg;
454 if (bar < 0 || bar > 5)
455 goto ret;
456 ret = pci_endpoint_test_bar(test, bar);
457 break;
458 case PCITEST_LEGACY_IRQ:
459 ret = pci_endpoint_test_legacy_irq(test);
460 break;
461 case PCITEST_MSI:
> 462 case PCITEST_MSIX:
463 ret = pci_endpoint_test_msi_irq(test, arg, cmd == PCITEST_MSIX);
464 break;
465 case PCITEST_WRITE:
466 ret = pci_endpoint_test_write(test, arg);
467 break;
468 case PCITEST_READ:
469 ret = pci_endpoint_test_read(test, arg);
470 break;
471 case PCITEST_COPY:
472 ret = pci_endpoint_test_copy(test, arg);
473 break;
474 }
475
476 ret:
477 mutex_unlock(&test->mutex);
478 return ret;
479 }
480
---
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: 27479 bytes --]
^ permalink raw reply
* [PATCH v4 1/5] PCI/AER: Define and allocate aer_stats structure for AER capable devices
From: Rajat Jain @ 2018-06-20 23:28 UTC (permalink / raw)
To: Bjorn Helgaas, Jonathan Corbet, Philippe Ombredanne, Kate Stewart,
Thomas Gleixner, Greg Kroah-Hartman, Frederick Lawler,
Oza Pawandeep, Keith Busch, Alexandru Gagniuc, Thomas Tai,
Steven Rostedt (VMware), linux-pci, linux-doc, linux-kernel,
Jes Sorensen, Kyle McMartin, rajatxjain, helgaas
Cc: Rajat Jain
In-Reply-To: <20180522222805.80314-1-rajatja@google.com>
Define a structure to hold the AER statistics. There are 2 groups
of statistics: dev_* counters that are to be collected for all AER
capable devices and rootport_* counters that are collected for all
(AER capable) rootports only. Allocate and free this structure when
device is added or released (thus counters survive the lifetime of the
device).
Signed-off-by: Rajat Jain <rajatja@google.com>
---
v4: Same as v3
v3: Merge everything in aer.c
drivers/pci/pcie/aer.c | 60 ++++++++++++++++++++++++++++++++++++++++++
drivers/pci/probe.c | 1 +
include/linux/pci.h | 3 +++
3 files changed, 64 insertions(+)
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index a2e88386af28..f9fa994b6c33 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -33,6 +33,9 @@
#define AER_ERROR_SOURCES_MAX 100
#define AER_MAX_MULTI_ERR_DEVICES 5 /* Not likely to have more */
+#define AER_MAX_TYPEOF_CORRECTABLE_ERRS 16 /* as per PCI_ERR_COR_STATUS */
+#define AER_MAX_TYPEOF_UNCORRECTABLE_ERRS 26 /* as per PCI_ERR_UNCOR_STATUS*/
+
struct aer_err_info {
struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES];
int error_dev_num;
@@ -76,6 +79,40 @@ struct aer_rpc {
*/
};
+/* AER stats for the device */
+struct aer_stats {
+
+ /*
+ * Fields for all AER capable devices. They indicate the errors
+ * "as seen by this device". Note that this may mean that if an
+ * end point is causing problems, the AER counters may increment
+ * at its link partner (e.g. root port) because the errors will be
+ * "seen" by the link partner and not the the problematic end point
+ * itself (which may report all counters as 0 as it never saw any
+ * problems).
+ */
+ /* Individual counters for different type of correctable errors */
+ u64 dev_cor_errs[AER_MAX_TYPEOF_CORRECTABLE_ERRS];
+ /* Individual counters for different type of uncorrectable errors */
+ u64 dev_uncor_errs[AER_MAX_TYPEOF_UNCORRECTABLE_ERRS];
+ /* Total number of correctable errors seen by this device */
+ u64 dev_total_cor_errs;
+ /* Total number of fatal uncorrectable errors seen by this device */
+ u64 dev_total_fatal_errs;
+ /* Total number of fatal uncorrectable errors seen by this device */
+ u64 dev_total_nonfatal_errs;
+
+ /*
+ * Fields for Root ports only, these indicate the total number of
+ * ERR_COR, ERR_FATAL, and ERR_NONFATAL messages received by the
+ * rootport, INCLUDING the ones that are generated internally (by
+ * the rootport itself)
+ */
+ u64 rootport_total_cor_errs;
+ u64 rootport_total_fatal_errs;
+ u64 rootport_total_nonfatal_errs;
+};
+
#define AER_LOG_TLP_MASKS (PCI_ERR_UNC_POISON_TLP| \
PCI_ERR_UNC_ECRC| \
PCI_ERR_UNC_UNSUP| \
@@ -402,12 +439,35 @@ int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
return 0;
}
+static int pci_aer_stats_init(struct pci_dev *pdev)
+{
+ pdev->aer_stats = kzalloc(sizeof(struct aer_stats), GFP_KERNEL);
+ if (!pdev->aer_stats) {
+ dev_err(&pdev->dev, "No memory for aer_stats\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void pci_aer_stats_exit(struct pci_dev *pdev)
+{
+ kfree(pdev->aer_stats);
+ pdev->aer_stats = NULL;
+}
+
int pci_aer_init(struct pci_dev *dev)
{
dev->aer_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+ if (!dev->aer_cap || pci_aer_stats_init(dev))
+ return -EIO;
return pci_cleanup_aer_error_status_regs(dev);
}
+void pci_aer_exit(struct pci_dev *dev)
+{
+ pci_aer_stats_exit(dev);
+}
+
#define AER_AGENT_RECEIVER 0
#define AER_AGENT_REQUESTER 1
#define AER_AGENT_COMPLETER 2
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ac876e32de4b..48edd0c9e4bc 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2064,6 +2064,7 @@ static void pci_configure_device(struct pci_dev *dev)
static void pci_release_capabilities(struct pci_dev *dev)
{
+ pci_aer_exit(dev);
pci_vpd_release(dev);
pci_iov_release(dev);
pci_free_cap_save_buffers(dev);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 340029b2fb38..8d59c6c19a19 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -299,6 +299,7 @@ struct pci_dev {
u8 hdr_type; /* PCI header type (`multi' flag masked out) */
#ifdef CONFIG_PCIEAER
u16 aer_cap; /* AER capability offset */
+ struct aer_stats *aer_stats; /* AER stats for this device */
#endif
u8 pcie_cap; /* PCIe capability offset */
u8 msi_cap; /* MSI capability offset */
@@ -1471,10 +1472,12 @@ static inline bool pcie_aspm_support_enabled(void) { return false; }
void pci_no_aer(void);
bool pci_aer_available(void);
int pci_aer_init(struct pci_dev *dev);
+void pci_aer_exit(struct pci_dev *dev);
#else
static inline void pci_no_aer(void) { }
static inline bool pci_aer_available(void) { return false; }
static inline int pci_aer_init(struct pci_dev *d) { return -ENODEV; }
+static inline void pci_aer_exit(struct pci_dev *d) { }
#endif
#ifdef CONFIG_PCIE_ECRC
--
2.18.0.rc1.244.gcf134e6275-goog
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v4 2/5] PCI/AER: Add sysfs stats for AER capable devices
From: Rajat Jain @ 2018-06-20 23:28 UTC (permalink / raw)
To: Bjorn Helgaas, Jonathan Corbet, Philippe Ombredanne, Kate Stewart,
Thomas Gleixner, Greg Kroah-Hartman, Frederick Lawler,
Oza Pawandeep, Keith Busch, Alexandru Gagniuc, Thomas Tai,
Steven Rostedt (VMware), linux-pci, linux-doc, linux-kernel,
Jes Sorensen, Kyle McMartin, rajatxjain, helgaas
Cc: Rajat Jain
In-Reply-To: <20180620232841.43922-1-rajatja@google.com>
Add the following AER sysfs stats to represent the counters for each
kind of error as seen by the device:
dev_total_cor_errs
dev_total_fatal_errs
dev_total_nonfatal_errs
Signed-off-by: Rajat Jain <rajatja@google.com>
---
v4: Same as v3
v3: Merge everything in aer.c, use "%llu" in place of "%llx"
drivers/pci/pci-sysfs.c | 3 ++
drivers/pci/pci.h | 4 ++-
drivers/pci/pcie/aer.c | 74 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 0c4653c1d2ce..9f1cb9051d7d 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1746,6 +1746,9 @@ static const struct attribute_group *pci_dev_attr_groups[] = {
#endif
&pci_bridge_attr_group,
&pcie_dev_attr_group,
+#ifdef CONFIG_PCIEAER
+ &aer_stats_attr_group,
+#endif
NULL,
};
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index c358e7a07f3f..9a28ec600225 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -181,7 +181,9 @@ extern const struct attribute_group *pci_dev_groups[];
extern const struct attribute_group *pcibus_groups[];
extern const struct device_type pci_dev_type;
extern const struct attribute_group *pci_bus_groups[];
-
+#ifdef CONFIG_PCIEAER
+extern const struct attribute_group aer_stats_attr_group;
+#endif
/**
* pci_match_one_device - Tell if a PCI device structure has a matching
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index f9fa994b6c33..ce0d675d7bd3 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -573,6 +573,79 @@ static const char *aer_agent_string[] = {
"Transmitter ID"
};
+#define aer_stats_aggregate_attr(field) \
+ static ssize_t \
+ field##_show(struct device *dev, struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct pci_dev *pdev = to_pci_dev(dev); \
+ return sprintf(buf, "%llu\n", pdev->aer_stats->field); \
+} \
+static DEVICE_ATTR_RO(field)
+
+aer_stats_aggregate_attr(dev_total_cor_errs);
+aer_stats_aggregate_attr(dev_total_fatal_errs);
+aer_stats_aggregate_attr(dev_total_nonfatal_errs);
+
+static struct attribute *aer_stats_attrs[] __ro_after_init = {
+ &dev_attr_dev_total_cor_errs.attr,
+ &dev_attr_dev_total_fatal_errs.attr,
+ &dev_attr_dev_total_nonfatal_errs.attr,
+ NULL
+};
+
+static umode_t aer_stats_attrs_are_visible(struct kobject *kobj,
+ struct attribute *a, int n)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ if (!pdev->aer_stats)
+ return 0;
+
+ return a->mode;
+}
+
+const struct attribute_group aer_stats_attr_group = {
+ .name = "aer_stats",
+ .attrs = aer_stats_attrs,
+ .is_visible = aer_stats_attrs_are_visible,
+};
+
+static void pci_dev_aer_stats_incr(struct pci_dev *pdev,
+ struct aer_err_info *info)
+{
+ int status, i, max = -1;
+ u64 *counter = NULL;
+ struct aer_stats *aer_stats = pdev->aer_stats;
+
+ if (!aer_stats)
+ return;
+
+ switch (info->severity) {
+ case AER_CORRECTABLE:
+ aer_stats->dev_total_cor_errs++;
+ counter = &aer_stats->dev_cor_errs[0];
+ max = AER_MAX_TYPEOF_CORRECTABLE_ERRS;
+ break;
+ case AER_NONFATAL:
+ aer_stats->dev_total_nonfatal_errs++;
+ counter = &aer_stats->dev_uncor_errs[0];
+ max = AER_MAX_TYPEOF_UNCORRECTABLE_ERRS;
+ break;
+ case AER_FATAL:
+ aer_stats->dev_total_fatal_errs++;
+ counter = &aer_stats->dev_uncor_errs[0];
+ max = AER_MAX_TYPEOF_UNCORRECTABLE_ERRS;
+ break;
+ }
+
+ status = (info->status & ~info->mask);
+ for (i = 0; i < max; i++)
+ if (status & (1 << i))
+ counter[i]++;
+}
+
static void __print_tlp_header(struct pci_dev *dev,
struct aer_header_log_regs *t)
{
@@ -605,6 +678,7 @@ static void __aer_print_error(struct pci_dev *dev,
pci_err(dev, " [%2d] Unknown Error Bit%s\n",
i, info->first_error == i ? " (First)" : "");
}
+ pci_dev_aer_stats_incr(dev, info);
}
static void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
--
2.18.0.rc1.244.gcf134e6275-goog
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v5 5/5] Documentation/ABI: Add details of PCI AER statistics
From: Rajat Jain @ 2018-06-20 23:41 UTC (permalink / raw)
To: Bjorn Helgaas, Jonathan Corbet, Philippe Ombredanne, Kate Stewart,
Thomas Gleixner, Greg Kroah-Hartman, Frederick Lawler,
Oza Pawandeep, Keith Busch, Alexandru Gagniuc, Thomas Tai,
Steven Rostedt (VMware), linux-pci, linux-doc, linux-kernel,
Jes Sorensen, Kyle McMartin, rajatxjain, helgaas
Cc: Rajat Jain
In-Reply-To: <20180620234147.48438-1-rajatja@google.com>
Add the PCI AER statistics details to
Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
and provide a pointer to it in
Documentation/PCI/pcieaer-howto.txt
Signed-off-by: Rajat Jain <rajatja@google.com>
---
v5: Same as v4
v4: Same as v3
v3: Add some more details
.../testing/sysfs-bus-pci-devices-aer_stats | 111 ++++++++++++++++++
Documentation/PCI/pcieaer-howto.txt | 5 +
2 files changed, 116 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
new file mode 100644
index 000000000000..3ed5a682be87
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
@@ -0,0 +1,111 @@
+==========================
+PCIe Device AER statistics
+==========================
+These attributes show up under all the devices that are AER capable. These
+statistical counters indicate the errors "as seen/reported by the device".
+Note that this may mean that if an end point is causing problems, the AER
+counters may increment at its link partner (e.g. root port) because the
+errors will be "seen" / reported by the link partner and not the the
+problematic end point itself (which may report all counters as 0 as it never
+saw any problems).
+
+Where: /sys/bus/pci/devices/<dev>/aer_stats/dev_total_cor_errs
+Date: May 2018
+Kernel Version: 4.17.0
+Contact: linux-pci@vger.kernel.org, rajatja@google.com
+Description: Total number of correctable errors seen and reported by this
+ PCI device using ERR_COR.
+
+Where: /sys/bus/pci/devices/<dev>/aer_stats/dev_total_fatal_errs
+Date: May 2018
+Kernel Version: 4.17.0
+Contact: linux-pci@vger.kernel.org, rajatja@google.com
+Description: Total number of uncorrectable fatal errors seen and reported
+ by this PCI device using ERR_FATAL.
+
+Where: /sys/bus/pci/devices/<dev>/aer_stats/dev_total_nonfatal_errs
+Date: May 2018
+Kernel Version: 4.17.0
+Contact: linux-pci@vger.kernel.org, rajatja@google.com
+Description: Total number of uncorrectable non-fatal errors seen and reported
+ by this PCI device using ERR_NONFATAL.
+
+Where: /sys/bus/pci/devices/<dev>/aer_stats/dev_breakdown_correctable
+Date: May 2018
+Kernel Version: 4.17.0
+Contact: linux-pci@vger.kernel.org, rajatja@google.com
+Description: Breakdown of correctable errors seen and reported by this
+ PCI device using ERR_COR. Note that the sum total of all errors
+ in dev_breakdown_correctable may exceed dev_total_cor_errs
+ because a device is allowed to merge multiple correctable and
+ send a single ERR_COR for them (which is what dev_total_cor_errs
+ counts). A sample output for this attribute looks like this:
+-----------------------------------------
+Receiver Error = 174
+Bad TLP = 19
+Bad DLLP = 3
+RELAY_NUM Rollover = 0
+Replay Timer Timeout = 1
+Advisory Non-Fatal = 0
+Corrected Internal Error = 0
+Header Log Overflow = 0
+-----------------------------------------
+
+Where: /sys/bus/pci/devices/<dev>/aer_stats/dev_breakdown_uncorrectable
+Date: May 2018
+Kernel Version: 4.17.0
+Contact: linux-pci@vger.kernel.org, rajatja@google.com
+Description: Breakdown of of correctable errors seen and reported by this
+ PCI device using ERR_FATAL or ERR_NONFATAL. Note that the sum
+ total of all errors in dev_breakdown_uncorrectable may exceed
+ (dev_total_fatal_errs + dev_total_nonfatal_errs) because a
+ device is allowed to merge multiple errors at the same severity
+ and send a single ERR_FATAL/ERR_NON_FATAL for them.
+ A sample output for this attribute looks like this:
+-----------------------------------------
+Undefined = 0
+Data Link Protocol = 0
+Surprise Down Error = 0
+Poisoned TLP = 0
+Flow Control Protocol = 0
+Completion Timeout = 0
+Completer Abort = 0
+Unexpected Completion = 0
+Receiver Overflow = 0
+Malformed TLP = 0
+ECRC = 0
+Unsupported Request = 0
+ACS Violation = 0
+Uncorrectable Internal Error = 0
+MC Blocked TLP = 0
+AtomicOp Egress Blocked = 0
+TLP Prefix Blocked Error = 0
+-----------------------------------------
+
+============================
+PCIe Rootport AER statistics
+============================
+These attributes showup under only the rootports that are AER capable. These
+indicate the number of error messages as "reported to" the rootport. Please note
+that the rootports also transmit (internally) the ERR_* messages for errors seen
+by the internal rootport PCI device, so these counters includes them and are
+thus cumulative of all the error messages on the PCI hierarchy originating
+at that root port.
+
+Where: /sys/bus/pci/devices/<dev>/aer_stats/rootport_total_cor_errs
+Date: May 2018
+Kernel Version: 4.17.0
+Contact: linux-pci@vger.kernel.org, rajatja@google.com
+Description: Total number of ERR_COR messages reported to rootport.
+
+Where: /sys/bus/pci/devices/<dev>/aer_stats/rootport_total_fatal_errs
+Date: May 2018
+Kernel Version: 4.17.0
+Contact: linux-pci@vger.kernel.org, rajatja@google.com
+Description: Total number of ERR_FATAL messages reported to rootport.
+
+Where: /sys/bus/pci/devices/<dev>/aer_stats/rootport_total_nonfatal_errs
+Date: May 2018
+Kernel Version: 4.17.0
+Contact: linux-pci@vger.kernel.org, rajatja@google.com
+Description: Total number of ERR_NONFATAL messages reported to rootport.
diff --git a/Documentation/PCI/pcieaer-howto.txt b/Documentation/PCI/pcieaer-howto.txt
index acd0dddd6bb8..91b6e677cb8c 100644
--- a/Documentation/PCI/pcieaer-howto.txt
+++ b/Documentation/PCI/pcieaer-howto.txt
@@ -73,6 +73,11 @@ In the example, 'Requester ID' means the ID of the device who sends
the error message to root port. Pls. refer to pci express specs for
other fields.
+2.4 AER Statistics / Counters
+
+When PCIe AER errors are captured, the counters / statistics are also exposed
+in form of sysfs attributes which are documented at
+Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
3. Developer Guide
--
2.18.0.rc1.244.gcf134e6275-goog
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v5 4/5] PCI/AER: Add sysfs attributes for rootport cumulative stats
From: Rajat Jain @ 2018-06-20 23:41 UTC (permalink / raw)
To: Bjorn Helgaas, Jonathan Corbet, Philippe Ombredanne, Kate Stewart,
Thomas Gleixner, Greg Kroah-Hartman, Frederick Lawler,
Oza Pawandeep, Keith Busch, Alexandru Gagniuc, Thomas Tai,
Steven Rostedt (VMware), linux-pci, linux-doc, linux-kernel,
Jes Sorensen, Kyle McMartin, rajatxjain, helgaas
Cc: Rajat Jain
In-Reply-To: <20180620234147.48438-1-rajatja@google.com>
Add sysfs attributes for rootport statistics (that are cumulative
of all the ERR_* messages seen on this PCI hierarchy).
Signed-off-by: Rajat Jain <rajatja@google.com>
---
v5: Same as v4
v4: Make pci_rootport_aer_stats_incr() static, 1 hunk of previous patch was included by mistake, fix that.
v3: Merge everything in aer.c
drivers/pci/pcie/aer.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index c989bb5bb6f1..d9def7fabd81 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -586,6 +586,9 @@ static DEVICE_ATTR_RO(field)
aer_stats_aggregate_attr(dev_total_cor_errs);
aer_stats_aggregate_attr(dev_total_fatal_errs);
aer_stats_aggregate_attr(dev_total_nonfatal_errs);
+aer_stats_aggregate_attr(rootport_total_cor_errs);
+aer_stats_aggregate_attr(rootport_total_fatal_errs);
+aer_stats_aggregate_attr(rootport_total_nonfatal_errs);
#define aer_stats_breakdown_attr(field, stats_array, strings_array) \
static ssize_t \
@@ -619,6 +622,9 @@ static struct attribute *aer_stats_attrs[] __ro_after_init = {
&dev_attr_dev_total_nonfatal_errs.attr,
&dev_attr_dev_breakdown_correctable.attr,
&dev_attr_dev_breakdown_uncorrectable.attr,
+ &dev_attr_rootport_total_cor_errs.attr,
+ &dev_attr_rootport_total_fatal_errs.attr,
+ &dev_attr_rootport_total_nonfatal_errs.attr,
NULL
};
@@ -631,6 +637,12 @@ static umode_t aer_stats_attrs_are_visible(struct kobject *kobj,
if (!pdev->aer_stats)
return 0;
+ if ((a == &dev_attr_rootport_total_cor_errs.attr ||
+ a == &dev_attr_rootport_total_fatal_errs.attr ||
+ a == &dev_attr_rootport_total_nonfatal_errs.attr) &&
+ pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT)
+ return 0;
+
return a->mode;
}
@@ -674,6 +686,25 @@ static void pci_dev_aer_stats_incr(struct pci_dev *pdev,
counter[i]++;
}
+static void pci_rootport_aer_stats_incr(struct pci_dev *pdev,
+ struct aer_err_source *e_src)
+{
+ struct aer_stats *aer_stats = pdev->aer_stats;
+
+ if (!aer_stats)
+ return;
+
+ if (e_src->status & PCI_ERR_ROOT_COR_RCV)
+ aer_stats->rootport_total_cor_errs++;
+
+ if (e_src->status & PCI_ERR_ROOT_UNCOR_RCV) {
+ if (e_src->status & PCI_ERR_ROOT_FATAL_RCV)
+ aer_stats->rootport_total_fatal_errs++;
+ else
+ aer_stats->rootport_total_nonfatal_errs++;
+ }
+}
+
static void __print_tlp_header(struct pci_dev *dev,
struct aer_header_log_regs *t)
{
@@ -1124,6 +1155,8 @@ static void aer_isr_one_error(struct aer_rpc *rpc,
struct pci_dev *pdev = rpc->rpd;
struct aer_err_info *e_info = &rpc->e_info;
+ pci_rootport_aer_stats_incr(pdev, e_src);
+
/*
* There is a possibility that both correctable error and
* uncorrectable error being logged. Report correctable error first.
--
2.18.0.rc1.244.gcf134e6275-goog
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v5 2/5] PCI/AER: Add sysfs stats for AER capable devices
From: Rajat Jain @ 2018-06-20 23:41 UTC (permalink / raw)
To: Bjorn Helgaas, Jonathan Corbet, Philippe Ombredanne, Kate Stewart,
Thomas Gleixner, Greg Kroah-Hartman, Frederick Lawler,
Oza Pawandeep, Keith Busch, Alexandru Gagniuc, Thomas Tai,
Steven Rostedt (VMware), linux-pci, linux-doc, linux-kernel,
Jes Sorensen, Kyle McMartin, rajatxjain, helgaas
Cc: Rajat Jain
In-Reply-To: <20180620234147.48438-1-rajatja@google.com>
Add the following AER sysfs stats to represent the counters for each
kind of error as seen by the device:
dev_total_cor_errs
dev_total_fatal_errs
dev_total_nonfatal_errs
Signed-off-by: Rajat Jain <rajatja@google.com>
---
v5: same as v4
v4: Same as v3
v3: Merge everything in aer.c, use "%llu" in place of "%llx"
drivers/pci/pci-sysfs.c | 3 ++
drivers/pci/pci.h | 4 ++-
drivers/pci/pcie/aer.c | 74 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 0c4653c1d2ce..9f1cb9051d7d 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1746,6 +1746,9 @@ static const struct attribute_group *pci_dev_attr_groups[] = {
#endif
&pci_bridge_attr_group,
&pcie_dev_attr_group,
+#ifdef CONFIG_PCIEAER
+ &aer_stats_attr_group,
+#endif
NULL,
};
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index c358e7a07f3f..9a28ec600225 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -181,7 +181,9 @@ extern const struct attribute_group *pci_dev_groups[];
extern const struct attribute_group *pcibus_groups[];
extern const struct device_type pci_dev_type;
extern const struct attribute_group *pci_bus_groups[];
-
+#ifdef CONFIG_PCIEAER
+extern const struct attribute_group aer_stats_attr_group;
+#endif
/**
* pci_match_one_device - Tell if a PCI device structure has a matching
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index f9fa994b6c33..ce0d675d7bd3 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -573,6 +573,79 @@ static const char *aer_agent_string[] = {
"Transmitter ID"
};
+#define aer_stats_aggregate_attr(field) \
+ static ssize_t \
+ field##_show(struct device *dev, struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct pci_dev *pdev = to_pci_dev(dev); \
+ return sprintf(buf, "%llu\n", pdev->aer_stats->field); \
+} \
+static DEVICE_ATTR_RO(field)
+
+aer_stats_aggregate_attr(dev_total_cor_errs);
+aer_stats_aggregate_attr(dev_total_fatal_errs);
+aer_stats_aggregate_attr(dev_total_nonfatal_errs);
+
+static struct attribute *aer_stats_attrs[] __ro_after_init = {
+ &dev_attr_dev_total_cor_errs.attr,
+ &dev_attr_dev_total_fatal_errs.attr,
+ &dev_attr_dev_total_nonfatal_errs.attr,
+ NULL
+};
+
+static umode_t aer_stats_attrs_are_visible(struct kobject *kobj,
+ struct attribute *a, int n)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ if (!pdev->aer_stats)
+ return 0;
+
+ return a->mode;
+}
+
+const struct attribute_group aer_stats_attr_group = {
+ .name = "aer_stats",
+ .attrs = aer_stats_attrs,
+ .is_visible = aer_stats_attrs_are_visible,
+};
+
+static void pci_dev_aer_stats_incr(struct pci_dev *pdev,
+ struct aer_err_info *info)
+{
+ int status, i, max = -1;
+ u64 *counter = NULL;
+ struct aer_stats *aer_stats = pdev->aer_stats;
+
+ if (!aer_stats)
+ return;
+
+ switch (info->severity) {
+ case AER_CORRECTABLE:
+ aer_stats->dev_total_cor_errs++;
+ counter = &aer_stats->dev_cor_errs[0];
+ max = AER_MAX_TYPEOF_CORRECTABLE_ERRS;
+ break;
+ case AER_NONFATAL:
+ aer_stats->dev_total_nonfatal_errs++;
+ counter = &aer_stats->dev_uncor_errs[0];
+ max = AER_MAX_TYPEOF_UNCORRECTABLE_ERRS;
+ break;
+ case AER_FATAL:
+ aer_stats->dev_total_fatal_errs++;
+ counter = &aer_stats->dev_uncor_errs[0];
+ max = AER_MAX_TYPEOF_UNCORRECTABLE_ERRS;
+ break;
+ }
+
+ status = (info->status & ~info->mask);
+ for (i = 0; i < max; i++)
+ if (status & (1 << i))
+ counter[i]++;
+}
+
static void __print_tlp_header(struct pci_dev *dev,
struct aer_header_log_regs *t)
{
@@ -605,6 +678,7 @@ static void __aer_print_error(struct pci_dev *dev,
pci_err(dev, " [%2d] Unknown Error Bit%s\n",
i, info->first_error == i ? " (First)" : "");
}
+ pci_dev_aer_stats_incr(dev, info);
}
static void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
--
2.18.0.rc1.244.gcf134e6275-goog
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v5 3/5] PCI/AER: Add sysfs attributes to provide breakdown of AERs
From: Rajat Jain @ 2018-06-20 23:41 UTC (permalink / raw)
To: Bjorn Helgaas, Jonathan Corbet, Philippe Ombredanne, Kate Stewart,
Thomas Gleixner, Greg Kroah-Hartman, Frederick Lawler,
Oza Pawandeep, Keith Busch, Alexandru Gagniuc, Thomas Tai,
Steven Rostedt (VMware), linux-pci, linux-doc, linux-kernel,
Jes Sorensen, Kyle McMartin, rajatxjain, helgaas
Cc: Rajat Jain
In-Reply-To: <20180620234147.48438-1-rajatja@google.com>
Add sysfs attributes to provide breakdown of the AERs seen,
into different type of correctable or uncorrectable errors:
dev_breakdown_correctable
dev_breakdown_uncorrectable
Signed-off-by: Rajat Jain <rajatja@google.com>
---
v5: Fix the signature
v4: use "%llu" in place of "%llx"
v3: Merge everything in aer.c
drivers/pci/pcie/aer.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ce0d675d7bd3..c989bb5bb6f1 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -587,10 +587,38 @@ aer_stats_aggregate_attr(dev_total_cor_errs);
aer_stats_aggregate_attr(dev_total_fatal_errs);
aer_stats_aggregate_attr(dev_total_nonfatal_errs);
+#define aer_stats_breakdown_attr(field, stats_array, strings_array) \
+ static ssize_t \
+ field##_show(struct device *dev, struct device_attribute *attr, \
+ char *buf) \
+{ \
+ unsigned int i; \
+ char *str = buf; \
+ struct pci_dev *pdev = to_pci_dev(dev); \
+ u64 *stats = pdev->aer_stats->stats_array; \
+ for (i = 0; i < ARRAY_SIZE(strings_array); i++) { \
+ if (strings_array[i]) \
+ str += sprintf(str, "%s = 0x%llu\n", \
+ strings_array[i], stats[i]); \
+ else if (stats[i]) \
+ str += sprintf(str, #stats_array "bit[%d] = 0x%llu\n",\
+ i, stats[i]); \
+ } \
+ return str-buf; \
+} \
+static DEVICE_ATTR_RO(field)
+
+aer_stats_breakdown_attr(dev_breakdown_correctable, dev_cor_errs,
+ aer_correctable_error_string);
+aer_stats_breakdown_attr(dev_breakdown_uncorrectable, dev_uncor_errs,
+ aer_uncorrectable_error_string);
+
static struct attribute *aer_stats_attrs[] __ro_after_init = {
&dev_attr_dev_total_cor_errs.attr,
&dev_attr_dev_total_fatal_errs.attr,
&dev_attr_dev_total_nonfatal_errs.attr,
+ &dev_attr_dev_breakdown_correctable.attr,
+ &dev_attr_dev_breakdown_uncorrectable.attr,
NULL
};
--
2.18.0.rc1.244.gcf134e6275-goog
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v5 1/5] PCI/AER: Define and allocate aer_stats structure for AER capable devices
From: Rajat Jain @ 2018-06-20 23:41 UTC (permalink / raw)
To: Bjorn Helgaas, Jonathan Corbet, Philippe Ombredanne, Kate Stewart,
Thomas Gleixner, Greg Kroah-Hartman, Frederick Lawler,
Oza Pawandeep, Keith Busch, Alexandru Gagniuc, Thomas Tai,
Steven Rostedt (VMware), linux-pci, linux-doc, linux-kernel,
Jes Sorensen, Kyle McMartin, rajatxjain, helgaas
Cc: Rajat Jain
In-Reply-To: <20180522222805.80314-1-rajatja@google.com>
Define a structure to hold the AER statistics. There are 2 groups
of statistics: dev_* counters that are to be collected for all AER
capable devices and rootport_* counters that are collected for all
(AER capable) rootports only. Allocate and free this structure when
device is added or released (thus counters survive the lifetime of the
device).
Signed-off-by: Rajat Jain <rajatja@google.com>
---
v5: Same as v4
v4: Same as v3
v3: Merge everything in aer.c
drivers/pci/pcie/aer.c | 60 ++++++++++++++++++++++++++++++++++++++++++
drivers/pci/probe.c | 1 +
include/linux/pci.h | 3 +++
3 files changed, 64 insertions(+)
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index a2e88386af28..f9fa994b6c33 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -33,6 +33,9 @@
#define AER_ERROR_SOURCES_MAX 100
#define AER_MAX_MULTI_ERR_DEVICES 5 /* Not likely to have more */
+#define AER_MAX_TYPEOF_CORRECTABLE_ERRS 16 /* as per PCI_ERR_COR_STATUS */
+#define AER_MAX_TYPEOF_UNCORRECTABLE_ERRS 26 /* as per PCI_ERR_UNCOR_STATUS*/
+
struct aer_err_info {
struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES];
int error_dev_num;
@@ -76,6 +79,40 @@ struct aer_rpc {
*/
};
+/* AER stats for the device */
+struct aer_stats {
+
+ /*
+ * Fields for all AER capable devices. They indicate the errors
+ * "as seen by this device". Note that this may mean that if an
+ * end point is causing problems, the AER counters may increment
+ * at its link partner (e.g. root port) because the errors will be
+ * "seen" by the link partner and not the the problematic end point
+ * itself (which may report all counters as 0 as it never saw any
+ * problems).
+ */
+ /* Individual counters for different type of correctable errors */
+ u64 dev_cor_errs[AER_MAX_TYPEOF_CORRECTABLE_ERRS];
+ /* Individual counters for different type of uncorrectable errors */
+ u64 dev_uncor_errs[AER_MAX_TYPEOF_UNCORRECTABLE_ERRS];
+ /* Total number of correctable errors seen by this device */
+ u64 dev_total_cor_errs;
+ /* Total number of fatal uncorrectable errors seen by this device */
+ u64 dev_total_fatal_errs;
+ /* Total number of fatal uncorrectable errors seen by this device */
+ u64 dev_total_nonfatal_errs;
+
+ /*
+ * Fields for Root ports only, these indicate the total number of
+ * ERR_COR, ERR_FATAL, and ERR_NONFATAL messages received by the
+ * rootport, INCLUDING the ones that are generated internally (by
+ * the rootport itself)
+ */
+ u64 rootport_total_cor_errs;
+ u64 rootport_total_fatal_errs;
+ u64 rootport_total_nonfatal_errs;
+};
+
#define AER_LOG_TLP_MASKS (PCI_ERR_UNC_POISON_TLP| \
PCI_ERR_UNC_ECRC| \
PCI_ERR_UNC_UNSUP| \
@@ -402,12 +439,35 @@ int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
return 0;
}
+static int pci_aer_stats_init(struct pci_dev *pdev)
+{
+ pdev->aer_stats = kzalloc(sizeof(struct aer_stats), GFP_KERNEL);
+ if (!pdev->aer_stats) {
+ dev_err(&pdev->dev, "No memory for aer_stats\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void pci_aer_stats_exit(struct pci_dev *pdev)
+{
+ kfree(pdev->aer_stats);
+ pdev->aer_stats = NULL;
+}
+
int pci_aer_init(struct pci_dev *dev)
{
dev->aer_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+ if (!dev->aer_cap || pci_aer_stats_init(dev))
+ return -EIO;
return pci_cleanup_aer_error_status_regs(dev);
}
+void pci_aer_exit(struct pci_dev *dev)
+{
+ pci_aer_stats_exit(dev);
+}
+
#define AER_AGENT_RECEIVER 0
#define AER_AGENT_REQUESTER 1
#define AER_AGENT_COMPLETER 2
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ac876e32de4b..48edd0c9e4bc 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2064,6 +2064,7 @@ static void pci_configure_device(struct pci_dev *dev)
static void pci_release_capabilities(struct pci_dev *dev)
{
+ pci_aer_exit(dev);
pci_vpd_release(dev);
pci_iov_release(dev);
pci_free_cap_save_buffers(dev);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 340029b2fb38..8d59c6c19a19 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -299,6 +299,7 @@ struct pci_dev {
u8 hdr_type; /* PCI header type (`multi' flag masked out) */
#ifdef CONFIG_PCIEAER
u16 aer_cap; /* AER capability offset */
+ struct aer_stats *aer_stats; /* AER stats for this device */
#endif
u8 pcie_cap; /* PCIe capability offset */
u8 msi_cap; /* MSI capability offset */
@@ -1471,10 +1472,12 @@ static inline bool pcie_aspm_support_enabled(void) { return false; }
void pci_no_aer(void);
bool pci_aer_available(void);
int pci_aer_init(struct pci_dev *dev);
+void pci_aer_exit(struct pci_dev *dev);
#else
static inline void pci_no_aer(void) { }
static inline bool pci_aer_available(void) { return false; }
static inline int pci_aer_init(struct pci_dev *d) { return -ENODEV; }
+static inline void pci_aer_exit(struct pci_dev *d) { }
#endif
#ifdef CONFIG_PCIE_ECRC
--
2.18.0.rc1.244.gcf134e6275-goog
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v5 02/11] PCI: Update xxx_pcie_ep_raise_irq() and pci_epc_raise_irq() signatures
From: Shawn Lin @ 2018-06-21 0:39 UTC (permalink / raw)
To: Gustavo Pimentel, adouglas
Cc: bhelgaas, lorenzo.pieralisi, Joao.Pinto, jingoohan1, kishon,
jesper.nilsson, sboyd, shawn.lin, linux-pci, linux-doc,
linux-kernel
In-Reply-To: <180c7a9743a67120e77ab198889c1373e91643b9.1529507416.git.gustavo.pimentel@synopsys.com>
On 2018/6/21 0:28, Gustavo Pimentel wrote:
> drivers/pci/controller/pcie-rockchip-ep.c | 2 +-
Acked-by: Shawn Lin <shawn.lin@rock-chips.com>
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 0/7] Uprobes: Support SDT markers having reference count (semaphore)
From: Ravi Bangoria @ 2018-06-21 2:35 UTC (permalink / raw)
To: Steven Rostedt
Cc: oleg, srikar, mhiramat, peterz, mingo, acme, alexander.shishkin,
jolsa, namhyung, linux-kernel, corbet, linux-doc, ananth,
alexis.berlemont, naveen.n.rao, Ravi Bangoria
In-Reply-To: <20180620123750.79811466@gandalf.local.home>
On 06/20/2018 10:07 PM, Steven Rostedt wrote:
> On Wed, 6 Jun 2018 14:03:37 +0530
> Ravi Bangoria <ravi.bangoria@linux.ibm.com> wrote:
>
>> Why RFC again:
>>
>> This series is different from earlier versions[1]. Earlier series
>> implemented this feature in trace_uprobe while this has implemented
>> the logic in core uprobe. Few reasons for this:
>> 1. One of the major reason was the deadlock between uprobe_lock and
>> mm->mmap inside trace_uprobe_mmap(). That deadlock was not easy to fix
>> because mm->mmap is not in control of trace_uprobe_mmap() and it has
>> to take uprobe_lock to loop over trace_uprobe list. More details can
>> be found at[2]. With this new approach, there are no deadlocks found
>> so far.
>> 2. Many of the core uprobe function and data-structures needs to be
>> exported to make earlier implementation simple. With this new approach,
>> reference counter logic is been implemented in core uprobe and thus
>> no need to export anything.
>
>
> A quick scan of the patches, I don't see anything controversial with
> them. Unless others have any qualms about it, I say repost as non RFC,
> and we can start doing a more thorough review.
Yes, I've posted it: https://lkml.org/lkml/2018/6/19/1324
I've copied you as well :) Please have a look.
Thanks,
Ravi
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v10 5/9] cpuset: Make sure that domain roots work properly with CPU hotplug
From: Waiman Long @ 2018-06-21 3:09 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Tejun Heo, Li Zefan, Johannes Weiner, Ingo Molnar, cgroups,
linux-kernel, linux-doc, kernel-team, pjt, luto, Mike Galbraith,
torvalds, Roman Gushchin, Juri Lelli, Patrick Bellasi
In-Reply-To: <20180620141538.GJ2494@hirez.programming.kicks-ass.net>
On 06/20/2018 10:15 PM, Peter Zijlstra wrote:
> On Mon, Jun 18, 2018 at 12:14:04PM +0800, Waiman Long wrote:
>> diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
>> index 5ee5e77..6ef3516 100644
>> --- a/Documentation/admin-guide/cgroup-v2.rst
>> +++ b/Documentation/admin-guide/cgroup-v2.rst
>> @@ -1626,6 +1626,13 @@ Cpuset Interface Files
>> 2) No CPU that has been distributed to child scheduling domain
>> roots is deleted.
>>
>> + When all the CPUs allocated to a scheduling domain are offlined,
>> + that scheduling domain will be temporaily gone and all the
>> + tasks in that scheduling domain will migrate to another one that
>> + belongs to the parent of the scheduling domain root. When any
>> + of those offlined CPUs is onlined again, a new scheduling domain
>> + will be re-created and the tasks will be migrated back.
>> +
> You should mention that this is a destructive operation. If any of the
> tasks had an affinity smaller than the original cgroup, that will be
> gone.
Thanks for the information. Will update the documentation to mention that.
Cheers,
Longman
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v6 0/2] Add ThunderX2 SoC Performance Monitoring Unit driver
From: Ganapatrao Kulkarni @ 2018-06-21 6:33 UTC (permalink / raw)
To: linux-doc, linux-kernel, linux-arm-kernel
Cc: Will.Deacon, mark.rutland, jnair, Robert.Richter, Vadim.Lomovtsev,
Jan.Glauber, gklkml16
This patchset adds PMU driver for Cavium's ThunderX2 SoC UNCORE devices.
The SoC has PMU support in L3 cache controller (L3C) and in the
DDR4 Memory Controller (DMC).
v6:
Rebased to 4.18-rc1
Updated with comments from John Garry[3]
[3] https://lkml.org/lkml/2018/5/17/408
v5:
-Incroporated review comments from Mark Rutland[2]
v4:
-Incroporated review comments from Mark Rutland[1]
[1] https://www.spinics.net/lists/arm-kernel/msg588563.html
[2] https://lkml.org/lkml/2018/4/26/376
v3:
- fixed warning reported by kbuild robot
v2:
- rebased to 4.12-rc1
- Removed Arch VULCAN dependency.
- update SMC call parameters as per latest firmware.
v1:
-Initial patch
Ganapatrao Kulkarni (2):
perf: uncore: Adding documentation for ThunderX2 pmu uncore driver
ThunderX2: Add Cavium ThunderX2 SoC UNCORE PMU driver
Documentation/perf/thunderx2-pmu.txt | 66 +++
drivers/perf/Kconfig | 8 +
drivers/perf/Makefile | 1 +
drivers/perf/thunderx2_pmu.c | 949 +++++++++++++++++++++++++++++++++++
include/linux/cpuhotplug.h | 1 +
5 files changed, 1025 insertions(+)
create mode 100644 Documentation/perf/thunderx2-pmu.txt
create mode 100644 drivers/perf/thunderx2_pmu.c
--
2.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v6 1/2] perf: uncore: Adding documentation for ThunderX2 pmu uncore driver
From: Ganapatrao Kulkarni @ 2018-06-21 6:33 UTC (permalink / raw)
To: linux-doc, linux-kernel, linux-arm-kernel
Cc: Will.Deacon, mark.rutland, jnair, Robert.Richter, Vadim.Lomovtsev,
Jan.Glauber, gklkml16
In-Reply-To: <20180621063338.20093-1-ganapatrao.kulkarni@cavium.com>
Documentation for the UNCORE PMUs on Cavium's ThunderX2 SoC.
The SoC has PMU support in its L3 cache controller (L3C) and in the
DDR4 Memory Controller (DMC).
Signed-off-by: Ganapatrao Kulkarni <ganapatrao.kulkarni@cavium.com>
---
Documentation/perf/thunderx2-pmu.txt | 66 ++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
create mode 100644 Documentation/perf/thunderx2-pmu.txt
diff --git a/Documentation/perf/thunderx2-pmu.txt b/Documentation/perf/thunderx2-pmu.txt
new file mode 100644
index 0000000..7d89935
--- /dev/null
+++ b/Documentation/perf/thunderx2-pmu.txt
@@ -0,0 +1,66 @@
+
+Cavium ThunderX2 SoC Performance Monitoring Unit (PMU UNCORE)
+==========================================================================
+
+ThunderX2 SoC PMU consists of independent system wide per Socket PMUs such
+as Level 3 Cache(L3C) and DDR4 Memory Controller(DMC).
+
+It has 8 independent DMC PMUs to capture performance events corresponding
+to 8 channels of DDR4 Memory Controller. There are 16 independent L3C PMUs
+to capture events corresponding to 16 tiles of L3 cache. Each PMU supports
+up to 4 counters.
+
+Counters are independently programmable and can be started and stopped
+individually. Each counter can be set to sample specific perf events.
+Counters are 32 bit and do not support overflow interrupt; they are
+sampled at every 2 seconds. The Counters register access are multiplexed
+across channels of DMC and L3C. The muxing(select channel) is done through
+write to a Secure register using smcc calls.
+
+PMU UNCORE (perf) driver:
+
+The thunderx2-pmu driver registers several perf PMUs for DMC and L3C devices.
+Each of the PMUs provides description of its available events
+and configuration options in sysfs.
+ see /sys/devices/uncore_<l3c_S_X/dmc_S_X/>
+
+S is socket id and X represents channel number.
+Each PMU can be used to sample up to 4 events simultaneously.
+
+The "format" directory describes format of the config (event ID).
+The "events" directory provides configuration templates for all
+supported event types that can be used with perf tool.
+
+For example, "uncore_dmc_0_0/cnt_cycles/" is an
+equivalent of "uncore_dmc_0_0/config=0x1/".
+
+Each perf driver also provides a "cpumask" sysfs attribute, which contains a
+single CPU ID of the processor which is likely to be used to handle all the
+PMU events. It will be the first online CPU from the NUMA node of PMU device.
+
+Example for perf tool use:
+
+perf stat -a -e \
+uncore_dmc_0_0/cnt_cycles/,\
+uncore_dmc_0_1/cnt_cycles/,\
+uncore_dmc_0_2/cnt_cycles/,\
+uncore_dmc_0_3/cnt_cycles/,\
+uncore_dmc_0_4/cnt_cycles/,\
+uncore_dmc_0_5/cnt_cycles/,\
+uncore_dmc_0_6/cnt_cycles/,\
+uncore_dmc_0_7/cnt_cycles/ sleep 1
+
+perf stat -a -e \
+uncore_dmc_0_0/cancelled_read_txns/,\
+uncore_dmc_0_0/cnt_cycles/,\
+uncore_dmc_0_0/consumed_read_txns/,\
+uncore_dmc_0_0/data_transfers/ sleep 1
+
+perf stat -a -e \
+uncore_l3c_0_0/l3_retry/,\
+uncore_l3c_0_0/read_hit/,\
+uncore_l3c_0_0/read_request/,\
+uncore_l3c_0_0/inv_request/ sleep 1
+
+The driver does not support sampling, therefore "perf record" will
+not work. Per-task (without "-a") perf sessions are not supported.
--
2.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v6 2/2] ThunderX2: Add Cavium ThunderX2 SoC UNCORE PMU driver
From: Ganapatrao Kulkarni @ 2018-06-21 6:33 UTC (permalink / raw)
To: linux-doc, linux-kernel, linux-arm-kernel
Cc: Will.Deacon, mark.rutland, jnair, Robert.Richter, Vadim.Lomovtsev,
Jan.Glauber, gklkml16
In-Reply-To: <20180621063338.20093-1-ganapatrao.kulkarni@cavium.com>
This patch adds a perf driver for the PMU UNCORE devices DDR4 Memory
Controller(DMC) and Level 3 Cache(L3C).
ThunderX2 has 8 independent DMC PMUs to capture performance events
corresponding to 8 channels of DDR4 Memory Controller and 16 independent
L3C PMUs to capture events corresponding to 16 tiles of L3 cache.
Each PMU supports up to 4 counters. All counters lack overflow interrupt
and are sampled periodically.
Signed-off-by: Ganapatrao Kulkarni <ganapatrao.kulkarni@cavium.com>
---
drivers/perf/Kconfig | 8 +
drivers/perf/Makefile | 1 +
drivers/perf/thunderx2_pmu.c | 949 +++++++++++++++++++++++++++++++++++++++++++
include/linux/cpuhotplug.h | 1 +
4 files changed, 959 insertions(+)
create mode 100644 drivers/perf/thunderx2_pmu.c
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 08ebaf7..ecedb9e 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -87,6 +87,14 @@ config QCOM_L3_PMU
Adds the L3 cache PMU into the perf events subsystem for
monitoring L3 cache events.
+config THUNDERX2_PMU
+ bool "Cavium ThunderX2 SoC PMU UNCORE"
+ depends on ARCH_THUNDER2 && ARM64 && ACPI
+ help
+ Provides support for ThunderX2 UNCORE events.
+ The SoC has PMU support in its L3 cache controller (L3C) and
+ in the DDR4 Memory Controller (DMC).
+
config XGENE_PMU
depends on ARCH_XGENE
bool "APM X-Gene SoC PMU"
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index b3902bd..909f27f 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -7,5 +7,6 @@ obj-$(CONFIG_ARM_PMU_ACPI) += arm_pmu_acpi.o
obj-$(CONFIG_HISI_PMU) += hisilicon/
obj-$(CONFIG_QCOM_L2_PMU) += qcom_l2_pmu.o
obj-$(CONFIG_QCOM_L3_PMU) += qcom_l3_pmu.o
+obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c
new file mode 100644
index 0000000..676e27e
--- /dev/null
+++ b/drivers/perf/thunderx2_pmu.c
@@ -0,0 +1,949 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CAVIUM THUNDERX2 SoC PMU UNCORE
+ * Copyright (C) 2018 Cavium Inc.
+ * Author: Ganapatrao Kulkarni <gkulkarni@cavium.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/arm-smccc.h>
+#include <linux/cpuhotplug.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+
+/* L3C and DMC has 16 and 8 channels per socket respectively.
+ * Each Channel supports UNCORE PMU device and consists of
+ * 4 independent programmable counters. Counters are 32 bit
+ * and do not support overflow interrupt, they need to be
+ * sampled before overflow(i.e, at every 2 seconds).
+ */
+
+#define UNCORE_MAX_COUNTERS 4
+#define UNCORE_DMC_MAX_CHANNELS 8
+#define UNCORE_L3_MAX_TILES 16
+
+#define UNCORE_HRTIMER_INTERVAL (2 * NSEC_PER_SEC)
+#define GET_EVENTID(ev) ((ev->hw.config) & 0x1ff)
+#define GET_COUNTERID(ev) ((ev->hw.idx) & 0xf)
+#define GET_CHANNELID(pmu_uncore) (pmu_uncore->channel)
+#define DMC_EVENT_CFG(idx, val) ((val) << (((idx) * 8) + 1))
+
+#define L3C_COUNTER_CTL 0xA8
+#define L3C_COUNTER_DATA 0xAC
+#define DMC_COUNTER_CTL 0x234
+#define DMC_COUNTER_DATA 0x240
+
+#define THUNDERX2_SMC_CALL_ID 0xC200FF00
+#define THUNDERX2_SMC_SET_CHANNEL 0xB010
+
+enum thunderx2_uncore_l3_events {
+ L3_EVENT_NONE,
+ L3_EVENT_NBU_CANCEL,
+ L3_EVENT_DIB_RETRY,
+ L3_EVENT_DOB_RETRY,
+ L3_EVENT_DIB_CREDIT_RETRY,
+ L3_EVENT_DOB_CREDIT_RETRY,
+ L3_EVENT_FORCE_RETRY,
+ L3_EVENT_IDX_CONFLICT_RETRY,
+ L3_EVENT_EVICT_CONFLICT_RETRY,
+ L3_EVENT_BANK_CONFLICT_RETRY,
+ L3_EVENT_FILL_ENTRY_RETRY,
+ L3_EVENT_EVICT_NOT_READY_RETRY,
+ L3_EVENT_L3_RETRY,
+ L3_EVENT_READ_REQ,
+ L3_EVENT_WRITE_BACK_REQ,
+ L3_EVENT_INVALIDATE_NWRITE_REQ,
+ L3_EVENT_INV_REQ,
+ L3_EVENT_SELF_REQ,
+ L3_EVENT_REQ,
+ L3_EVENT_EVICT_REQ,
+ L3_EVENT_INVALIDATE_NWRITE_HIT,
+ L3_EVENT_INVALIDATE_HIT,
+ L3_EVENT_SELF_HIT,
+ L3_EVENT_READ_HIT,
+ L3_EVENT_MAX,
+};
+
+enum thunderx2_uncore_dmc_events {
+ DMC_EVENT_NONE,
+ DMC_EVENT_COUNT_CYCLES,
+ DMC_EVENT_RES2,
+ DMC_EVENT_RES3,
+ DMC_EVENT_RES4,
+ DMC_EVENT_RES5,
+ DMC_EVENT_RES6,
+ DMC_EVENT_RES7,
+ DMC_EVENT_RES8,
+ DMC_EVENT_READ_64B_TXNS,
+ DMC_EVENT_READ_BELOW_64B_TXNS,
+ DMC_EVENT_WRITE_TXNS,
+ DMC_EVENT_TXN_CYCLES,
+ DMC_EVENT_DATA_TRANSFERS,
+ DMC_EVENT_CANCELLED_READ_TXNS,
+ DMC_EVENT_CONSUMED_READ_TXNS,
+ DMC_EVENT_MAX,
+};
+
+enum thunderx2_uncore_type {
+ PMU_TYPE_L3C,
+ PMU_TYPE_DMC,
+ PMU_TYPE_INVALID,
+};
+
+/*
+ * pmu on each socket has 2 uncore devices(dmc and l3),
+ * each uncore device has up to 16 channels, each channel can sample
+ * events independently with counters up to 4.
+ */
+struct thunderx2_pmu_uncore_channel {
+ struct pmu pmu;
+ struct hlist_node node;
+ struct thunderx2_pmu_uncore_dev *uncore_dev;
+ int channel;
+ int cpu;
+ DECLARE_BITMAP(active_counters, UNCORE_MAX_COUNTERS);
+ struct perf_event *events[UNCORE_MAX_COUNTERS];
+ struct hrtimer hrtimer;
+ /* to sync counter alloc/release */
+ raw_spinlock_t lock;
+};
+
+struct thunderx2_pmu_uncore_dev {
+ char *name;
+ struct device *dev;
+ enum thunderx2_uncore_type type;
+ void __iomem *base;
+ int node;
+ u32 max_counters;
+ u32 max_channels;
+ u32 max_events;
+ u64 hrtimer_interval;
+ /* this lock synchronizes across channels */
+ raw_spinlock_t lock;
+ const struct attribute_group **attr_groups;
+ void (*init_cntr_base)(struct perf_event *event,
+ struct thunderx2_pmu_uncore_dev *uncore_dev);
+ void (*select_channel)(struct perf_event *event);
+ void (*stop_event)(struct perf_event *event);
+ void (*start_event)(struct perf_event *event, int flags);
+};
+
+static inline struct thunderx2_pmu_uncore_channel *
+pmu_to_thunderx2_pmu_uncore(struct pmu *pmu)
+{
+ return container_of(pmu, struct thunderx2_pmu_uncore_channel, pmu);
+}
+
+/*
+ * sysfs format attributes
+ */
+static ssize_t thunderx2_pmu_format_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dev_ext_attribute *eattr;
+
+ eattr = container_of(attr, struct dev_ext_attribute, attr);
+ return sprintf(buf, "%s\n", (char *) eattr->var);
+}
+
+#define FORMAT_ATTR(_name, _config) \
+ (&((struct dev_ext_attribute[]) { \
+ { \
+ .attr = __ATTR(_name, 0444, thunderx2_pmu_format_show, NULL), \
+ .var = (void *) _config, \
+ } \
+ })[0].attr.attr)
+
+static struct attribute *l3c_pmu_format_attrs[] = {
+ FORMAT_ATTR(event, "config:0-4"),
+ NULL,
+};
+
+static struct attribute *dmc_pmu_format_attrs[] = {
+ FORMAT_ATTR(event, "config:0-4"),
+ NULL,
+};
+
+static const struct attribute_group l3c_pmu_format_attr_group = {
+ .name = "format",
+ .attrs = l3c_pmu_format_attrs,
+};
+
+static const struct attribute_group dmc_pmu_format_attr_group = {
+ .name = "format",
+ .attrs = dmc_pmu_format_attrs,
+};
+
+/*
+ * sysfs event attributes
+ */
+static ssize_t thunderx2_pmu_event_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dev_ext_attribute *eattr;
+
+ eattr = container_of(attr, struct dev_ext_attribute, attr);
+ return sprintf(buf, "config=0x%lx\n", (unsigned long) eattr->var);
+}
+
+#define EVENT_ATTR(_name, _config) \
+ (&((struct dev_ext_attribute[]) { \
+ { \
+ .attr = __ATTR(_name, 0444, thunderx2_pmu_event_show, NULL), \
+ .var = (void *) _config, \
+ } \
+ })[0].attr.attr)
+
+static struct attribute *l3c_pmu_events_attrs[] = {
+ EVENT_ATTR(nbu_cancel, L3_EVENT_NBU_CANCEL),
+ EVENT_ATTR(dib_retry, L3_EVENT_DIB_RETRY),
+ EVENT_ATTR(dob_retry, L3_EVENT_DOB_RETRY),
+ EVENT_ATTR(dib_credit_retry, L3_EVENT_DIB_CREDIT_RETRY),
+ EVENT_ATTR(dob_credit_retry, L3_EVENT_DOB_CREDIT_RETRY),
+ EVENT_ATTR(force_retry, L3_EVENT_FORCE_RETRY),
+ EVENT_ATTR(idx_conflict_retry, L3_EVENT_IDX_CONFLICT_RETRY),
+ EVENT_ATTR(evict_conflict_retry, L3_EVENT_EVICT_CONFLICT_RETRY),
+ EVENT_ATTR(bank_conflict_retry, L3_EVENT_BANK_CONFLICT_RETRY),
+ EVENT_ATTR(fill_entry_retry, L3_EVENT_FILL_ENTRY_RETRY),
+ EVENT_ATTR(evict_not_ready_retry, L3_EVENT_EVICT_NOT_READY_RETRY),
+ EVENT_ATTR(l3_retry, L3_EVENT_L3_RETRY),
+ EVENT_ATTR(read_request, L3_EVENT_READ_REQ),
+ EVENT_ATTR(write_back_request, L3_EVENT_WRITE_BACK_REQ),
+ EVENT_ATTR(inv_nwrite_request, L3_EVENT_INVALIDATE_NWRITE_REQ),
+ EVENT_ATTR(inv_request, L3_EVENT_INV_REQ),
+ EVENT_ATTR(self_request, L3_EVENT_SELF_REQ),
+ EVENT_ATTR(request, L3_EVENT_REQ),
+ EVENT_ATTR(evict_request, L3_EVENT_EVICT_REQ),
+ EVENT_ATTR(inv_nwrite_hit, L3_EVENT_INVALIDATE_NWRITE_HIT),
+ EVENT_ATTR(inv_hit, L3_EVENT_INVALIDATE_HIT),
+ EVENT_ATTR(self_hit, L3_EVENT_SELF_HIT),
+ EVENT_ATTR(read_hit, L3_EVENT_READ_HIT),
+ NULL,
+};
+
+static struct attribute *dmc_pmu_events_attrs[] = {
+ EVENT_ATTR(cnt_cycles, DMC_EVENT_COUNT_CYCLES),
+ EVENT_ATTR(read_64b_txns, DMC_EVENT_READ_64B_TXNS),
+ EVENT_ATTR(read_below_64b_txns, DMC_EVENT_READ_BELOW_64B_TXNS),
+ EVENT_ATTR(write_txns, DMC_EVENT_WRITE_TXNS),
+ EVENT_ATTR(txn_cycles, DMC_EVENT_TXN_CYCLES),
+ EVENT_ATTR(data_transfers, DMC_EVENT_DATA_TRANSFERS),
+ EVENT_ATTR(cancelled_read_txns, DMC_EVENT_CANCELLED_READ_TXNS),
+ EVENT_ATTR(consumed_read_txns, DMC_EVENT_CONSUMED_READ_TXNS),
+ NULL,
+};
+
+static const struct attribute_group l3c_pmu_events_attr_group = {
+ .name = "events",
+ .attrs = l3c_pmu_events_attrs,
+};
+
+static const struct attribute_group dmc_pmu_events_attr_group = {
+ .name = "events",
+ .attrs = dmc_pmu_events_attrs,
+};
+
+/*
+ * sysfs cpumask attributes
+ */
+static ssize_t cpumask_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct cpumask cpu_mask;
+ struct thunderx2_pmu_uncore_channel *pmu_uncore =
+ pmu_to_thunderx2_pmu_uncore(dev_get_drvdata(dev));
+
+ cpumask_clear(&cpu_mask);
+ cpumask_set_cpu(pmu_uncore->cpu, &cpu_mask);
+ return cpumap_print_to_pagebuf(true, buf, &cpu_mask);
+}
+static DEVICE_ATTR_RO(cpumask);
+
+static struct attribute *thunderx2_pmu_cpumask_attrs[] = {
+ &dev_attr_cpumask.attr,
+ NULL,
+};
+
+static const struct attribute_group pmu_cpumask_attr_group = {
+ .attrs = thunderx2_pmu_cpumask_attrs,
+};
+
+/*
+ * Per PMU device attribute groups
+ */
+static const struct attribute_group *l3c_pmu_attr_groups[] = {
+ &l3c_pmu_format_attr_group,
+ &pmu_cpumask_attr_group,
+ &l3c_pmu_events_attr_group,
+ NULL
+};
+
+static const struct attribute_group *dmc_pmu_attr_groups[] = {
+ &dmc_pmu_format_attr_group,
+ &pmu_cpumask_attr_group,
+ &dmc_pmu_events_attr_group,
+ NULL
+};
+
+static inline u32 reg_readl(unsigned long addr)
+{
+ return readl((void __iomem *)addr);
+}
+
+static inline void reg_writel(u32 val, unsigned long addr)
+{
+ writel(val, (void __iomem *)addr);
+}
+
+static int alloc_counter(struct thunderx2_pmu_uncore_channel *pmu_uncore)
+{
+ int counter;
+
+ raw_spin_lock(&pmu_uncore->lock);
+ counter = find_first_zero_bit(pmu_uncore->active_counters,
+ pmu_uncore->uncore_dev->max_counters);
+ if (counter == pmu_uncore->uncore_dev->max_counters) {
+ raw_spin_unlock(&pmu_uncore->lock);
+ return -ENOSPC;
+ }
+ set_bit(counter, pmu_uncore->active_counters);
+ raw_spin_unlock(&pmu_uncore->lock);
+ return counter;
+}
+
+static void free_counter(
+ struct thunderx2_pmu_uncore_channel *pmu_uncore, int counter)
+{
+ raw_spin_lock(&pmu_uncore->lock);
+ clear_bit(counter, pmu_uncore->active_counters);
+ raw_spin_unlock(&pmu_uncore->lock);
+}
+
+/*
+ * DMC and L3 counter interface is muxed across all channels.
+ * hence we need to select the channel before accessing counter
+ * data/control registers.
+ *
+ * L3 Tile and DMC channel selection is through SMC call
+ * SMC call arguments,
+ * x0 = THUNDERX2_SMC_CALL_ID (Vendor SMC call Id)
+ * x1 = THUNDERX2_SMC_SET_CHANNEL (Id to set DMC/L3C channel)
+ * x2 = Node id
+ * x3 = DMC(1)/L3C(0)
+ * x4 = channel Id
+ */
+static void uncore_select_channel(struct perf_event *event)
+{
+ struct arm_smccc_res res;
+ struct thunderx2_pmu_uncore_channel *pmu_uncore =
+ pmu_to_thunderx2_pmu_uncore(event->pmu);
+ struct thunderx2_pmu_uncore_dev *uncore_dev =
+ pmu_uncore->uncore_dev;
+
+ arm_smccc_smc(THUNDERX2_SMC_CALL_ID, THUNDERX2_SMC_SET_CHANNEL,
+ uncore_dev->node, uncore_dev->type,
+ pmu_uncore->channel, 0, 0, 0, &res);
+ if (res.a0) {
+ dev_err(uncore_dev->dev,
+ "SMC to Select channel failed for PMU UNCORE[%s]\n",
+ pmu_uncore->uncore_dev->name);
+ }
+}
+
+/* early probe for firmware support */
+static int __init test_uncore_select_channel_early(struct device *dev)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(THUNDERX2_SMC_CALL_ID, THUNDERX2_SMC_SET_CHANNEL,
+ dev_to_node(dev), 0, 0, 0, 0, 0, &res);
+ if (res.a0) {
+ dev_err(dev, "No Firmware support for PMU UNCORE(%d)\n",
+ dev_to_node(dev));
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static void uncore_start_event_l3c(struct perf_event *event, int flags)
+{
+ u32 val;
+ struct hw_perf_event *hwc = &event->hw;
+
+ /* event id encoded in bits [07:03] */
+ val = GET_EVENTID(event) << 3;
+ reg_writel(val, hwc->config_base);
+ local64_set(&hwc->prev_count, 0);
+ reg_writel(0, hwc->event_base);
+}
+
+static void uncore_stop_event_l3c(struct perf_event *event)
+{
+ reg_writel(0, event->hw.config_base);
+}
+
+static void uncore_start_event_dmc(struct perf_event *event, int flags)
+{
+ u32 val;
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = GET_COUNTERID(event);
+ int event_type = GET_EVENTID(event);
+
+ /* enable and start counters.
+ * 8 bits for each counter, bits[05:01] of a counter to set event type.
+ */
+ val = reg_readl(hwc->config_base);
+ val &= ~DMC_EVENT_CFG(idx, 0x1f);
+ val |= DMC_EVENT_CFG(idx, event_type);
+ reg_writel(val, hwc->config_base);
+ local64_set(&hwc->prev_count, 0);
+ reg_writel(0, hwc->event_base);
+}
+
+static void uncore_stop_event_dmc(struct perf_event *event)
+{
+ u32 val;
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = GET_COUNTERID(event);
+
+ /* clear event type(bits[05:01]) to stop counter */
+ val = reg_readl(hwc->config_base);
+ val &= ~DMC_EVENT_CFG(idx, 0x1f);
+ reg_writel(val, hwc->config_base);
+}
+
+static void init_cntr_base_l3c(struct perf_event *event,
+ struct thunderx2_pmu_uncore_dev *uncore_dev)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ /* counter ctrl/data reg offset at 8 */
+ hwc->config_base = (unsigned long)uncore_dev->base
+ + L3C_COUNTER_CTL + (8 * GET_COUNTERID(event));
+ hwc->event_base = (unsigned long)uncore_dev->base
+ + L3C_COUNTER_DATA + (8 * GET_COUNTERID(event));
+}
+
+static void init_cntr_base_dmc(struct perf_event *event,
+ struct thunderx2_pmu_uncore_dev *uncore_dev)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ hwc->config_base = (unsigned long)uncore_dev->base
+ + DMC_COUNTER_CTL;
+ /* counter data reg offset at 0xc */
+ hwc->event_base = (unsigned long)uncore_dev->base
+ + DMC_COUNTER_DATA + (0xc * GET_COUNTERID(event));
+}
+
+static void thunderx2_uncore_update(struct perf_event *event)
+{
+ s64 prev, new = 0;
+ u64 delta;
+ struct hw_perf_event *hwc = &event->hw;
+ struct thunderx2_pmu_uncore_channel *pmu_uncore;
+ enum thunderx2_uncore_type type;
+
+ pmu_uncore = pmu_to_thunderx2_pmu_uncore(event->pmu);
+ type = pmu_uncore->uncore_dev->type;
+
+ pmu_uncore->uncore_dev->select_channel(event);
+
+ new = reg_readl(hwc->event_base);
+ prev = local64_xchg(&hwc->prev_count, new);
+
+ /* handles rollover of 32 bit counter */
+ delta = (u32)(((1UL << 32) - prev) + new);
+ local64_add(delta, &event->count);
+}
+
+enum thunderx2_uncore_type get_uncore_device_type(struct acpi_device *adev)
+{
+ int i = 0;
+ struct acpi_uncore_device {
+ __u8 id[ACPI_ID_LEN];
+ enum thunderx2_uncore_type type;
+ } devices[] = {
+ {"CAV901D", PMU_TYPE_L3C},
+ {"CAV901F", PMU_TYPE_DMC},
+ {"", PMU_TYPE_INVALID}
+ };
+
+ while (devices[i].type != PMU_TYPE_INVALID) {
+ if (!strcmp(acpi_device_hid(adev), devices[i].id))
+ return devices[i].type;
+ i++;
+ }
+ return PMU_TYPE_INVALID;
+}
+
+/*
+ * We must NOT create groups containing events from multiple hardware PMUs,
+ * although mixing different software and hardware PMUs is allowed.
+ */
+static bool thunderx2_uncore_validate_event_group(struct perf_event *event)
+{
+ struct pmu *pmu = event->pmu;
+ struct perf_event *leader = event->group_leader;
+ struct perf_event *sibling;
+ int counters = 0;
+
+ if (leader->pmu != event->pmu && !is_software_event(leader))
+ return false;
+
+ for_each_sibling_event(sibling, event->group_leader) {
+ if (is_software_event(sibling))
+ continue;
+ if (sibling->pmu != pmu)
+ return false;
+ counters++;
+ }
+
+ /*
+ * If the group requires more counters than the HW has,
+ * it cannot ever be scheduled.
+ */
+ return counters < UNCORE_MAX_COUNTERS;
+}
+
+static int thunderx2_uncore_event_init(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct thunderx2_pmu_uncore_channel *pmu_uncore;
+
+ /* Test the event attr type check for PMU enumeration */
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ /*
+ * SOC PMU counters are shared across all cores.
+ * Therefore, it does not support per-process mode.
+ * Also, it does not support event sampling mode.
+ */
+ if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+ return -EINVAL;
+
+ /* SOC counters do not have usr/os/guest/host bits */
+ if (event->attr.exclude_user || event->attr.exclude_kernel ||
+ event->attr.exclude_host || event->attr.exclude_guest)
+ return -EINVAL;
+
+ if (event->cpu < 0)
+ return -EINVAL;
+
+ pmu_uncore = pmu_to_thunderx2_pmu_uncore(event->pmu);
+ event->cpu = pmu_uncore->cpu;
+
+ if (event->attr.config >= pmu_uncore->uncore_dev->max_events)
+ return -EINVAL;
+
+ /* store event id */
+ hwc->config = event->attr.config;
+
+ /* Validate the group */
+ if (!thunderx2_uncore_validate_event_group(event))
+ return -EINVAL;
+
+ return 0;
+}
+
+static void thunderx2_uncore_start(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct thunderx2_pmu_uncore_channel *pmu_uncore;
+ struct thunderx2_pmu_uncore_dev *uncore_dev;
+ unsigned long irqflags;
+
+ hwc->state = 0;
+ pmu_uncore = pmu_to_thunderx2_pmu_uncore(event->pmu);
+ uncore_dev = pmu_uncore->uncore_dev;
+
+ raw_spin_lock_irqsave(&uncore_dev->lock, irqflags);
+ uncore_dev->select_channel(event);
+ uncore_dev->start_event(event, flags);
+ raw_spin_unlock_irqrestore(&uncore_dev->lock, irqflags);
+
+ perf_event_update_userpage(event);
+
+ if (!find_last_bit(pmu_uncore->active_counters,
+ pmu_uncore->uncore_dev->max_counters)) {
+ hrtimer_start(&pmu_uncore->hrtimer,
+ ns_to_ktime(uncore_dev->hrtimer_interval),
+ HRTIMER_MODE_REL_PINNED);
+ }
+}
+
+static void thunderx2_uncore_stop(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct thunderx2_pmu_uncore_channel *pmu_uncore;
+ struct thunderx2_pmu_uncore_dev *uncore_dev;
+ unsigned long irqflags;
+
+ if (hwc->state & PERF_HES_UPTODATE)
+ return;
+
+ pmu_uncore = pmu_to_thunderx2_pmu_uncore(event->pmu);
+ uncore_dev = pmu_uncore->uncore_dev;
+
+ raw_spin_lock_irqsave(&uncore_dev->lock, irqflags);
+
+ uncore_dev->select_channel(event);
+ uncore_dev->stop_event(event);
+
+ WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+ hwc->state |= PERF_HES_STOPPED;
+ if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+ thunderx2_uncore_update(event);
+ hwc->state |= PERF_HES_UPTODATE;
+ }
+ raw_spin_unlock_irqrestore(&uncore_dev->lock, irqflags);
+}
+
+static int thunderx2_uncore_add(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct thunderx2_pmu_uncore_channel *pmu_uncore;
+ struct thunderx2_pmu_uncore_dev *uncore_dev;
+
+ pmu_uncore = pmu_to_thunderx2_pmu_uncore(event->pmu);
+ uncore_dev = pmu_uncore->uncore_dev;
+
+ /* Allocate a free counter */
+ hwc->idx = alloc_counter(pmu_uncore);
+ if (hwc->idx < 0)
+ return -EAGAIN;
+
+ pmu_uncore->events[hwc->idx] = event;
+ /* set counter control and data registers base address */
+ uncore_dev->init_cntr_base(event, uncore_dev);
+
+ hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+ if (flags & PERF_EF_START)
+ thunderx2_uncore_start(event, flags);
+
+ return 0;
+}
+
+static void thunderx2_uncore_del(struct perf_event *event, int flags)
+{
+ struct thunderx2_pmu_uncore_channel *pmu_uncore =
+ pmu_to_thunderx2_pmu_uncore(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+
+ thunderx2_uncore_stop(event, PERF_EF_UPDATE);
+
+ /* clear the assigned counter */
+ free_counter(pmu_uncore, GET_COUNTERID(event));
+
+ perf_event_update_userpage(event);
+ pmu_uncore->events[hwc->idx] = NULL;
+ hwc->idx = -1;
+}
+
+static void thunderx2_uncore_read(struct perf_event *event)
+{
+ unsigned long irqflags;
+ struct thunderx2_pmu_uncore_channel *pmu_uncore =
+ pmu_to_thunderx2_pmu_uncore(event->pmu);
+
+ raw_spin_lock_irqsave(&pmu_uncore->uncore_dev->lock, irqflags);
+ thunderx2_uncore_update(event);
+ raw_spin_unlock_irqrestore(&pmu_uncore->uncore_dev->lock, irqflags);
+}
+
+static enum hrtimer_restart thunderx2_uncore_hrtimer_callback(
+ struct hrtimer *hrt)
+{
+ struct thunderx2_pmu_uncore_channel *pmu_uncore;
+ unsigned long irqflags;
+ int idx;
+ bool restart_timer = false;
+
+ pmu_uncore = container_of(hrt, struct thunderx2_pmu_uncore_channel,
+ hrtimer);
+
+ raw_spin_lock_irqsave(&pmu_uncore->uncore_dev->lock, irqflags);
+ for_each_set_bit(idx, pmu_uncore->active_counters,
+ pmu_uncore->uncore_dev->max_counters) {
+ struct perf_event *event = pmu_uncore->events[idx];
+
+ thunderx2_uncore_update(event);
+ restart_timer = true;
+ }
+ raw_spin_unlock_irqrestore(&pmu_uncore->uncore_dev->lock, irqflags);
+
+ if (restart_timer)
+ hrtimer_forward_now(hrt,
+ ns_to_ktime(
+ pmu_uncore->uncore_dev->hrtimer_interval));
+
+ return restart_timer ? HRTIMER_RESTART : HRTIMER_NORESTART;
+}
+
+static int thunderx2_pmu_uncore_register(
+ struct thunderx2_pmu_uncore_channel *pmu_uncore)
+{
+ struct device *dev = pmu_uncore->uncore_dev->dev;
+ char *name = pmu_uncore->uncore_dev->name;
+ int channel = pmu_uncore->channel;
+
+ /* Perf event registration */
+ pmu_uncore->pmu = (struct pmu) {
+ .attr_groups = pmu_uncore->uncore_dev->attr_groups,
+ .task_ctx_nr = perf_invalid_context,
+ .event_init = thunderx2_uncore_event_init,
+ .add = thunderx2_uncore_add,
+ .del = thunderx2_uncore_del,
+ .start = thunderx2_uncore_start,
+ .stop = thunderx2_uncore_stop,
+ .read = thunderx2_uncore_read,
+ };
+
+ pmu_uncore->pmu.name = devm_kasprintf(dev, GFP_KERNEL,
+ "%s_%d", name, channel);
+
+ return perf_pmu_register(&pmu_uncore->pmu, pmu_uncore->pmu.name, -1);
+}
+
+static int thunderx2_pmu_uncore_add(struct thunderx2_pmu_uncore_dev *uncore_dev,
+ int channel)
+{
+ struct thunderx2_pmu_uncore_channel *pmu_uncore;
+ int ret, cpu;
+
+ pmu_uncore = devm_kzalloc(uncore_dev->dev, sizeof(*pmu_uncore),
+ GFP_KERNEL);
+ if (!pmu_uncore)
+ return -ENOMEM;
+
+ cpu = cpumask_any_and(cpumask_of_node(uncore_dev->node),
+ cpu_online_mask);
+ if (cpu >= nr_cpu_ids)
+ return -EINVAL;
+
+ pmu_uncore->cpu = cpu;
+ pmu_uncore->channel = channel;
+ pmu_uncore->uncore_dev = uncore_dev;
+
+ hrtimer_init(&pmu_uncore->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ pmu_uncore->hrtimer.function = thunderx2_uncore_hrtimer_callback;
+
+ ret = thunderx2_pmu_uncore_register(pmu_uncore);
+ if (ret) {
+ dev_err(uncore_dev->dev, "%s PMU: Failed to init driver\n",
+ uncore_dev->name);
+ return -ENODEV;
+ }
+
+ /* register hotplug callback for the pmu */
+ ret = cpuhp_state_add_instance(
+ CPUHP_AP_PERF_ARM_THUNDERX2_UNCORE_ONLINE,
+ &pmu_uncore->node);
+ if (ret) {
+ dev_err(uncore_dev->dev, "Error %d registering hotplug", ret);
+ return ret;
+ }
+
+ dev_dbg(uncore_dev->dev, "%s PMU UNCORE registered\n",
+ pmu_uncore->pmu.name);
+ return ret;
+}
+
+static struct thunderx2_pmu_uncore_dev *init_pmu_uncore_dev(
+ struct device *dev, acpi_handle handle,
+ struct acpi_device *adev, u32 type)
+{
+ struct thunderx2_pmu_uncore_dev *uncore_dev;
+ void __iomem *base;
+ struct resource res;
+ struct resource_entry *rentry;
+ struct list_head list;
+ int ret;
+
+ INIT_LIST_HEAD(&list);
+ ret = acpi_dev_get_resources(adev, &list, NULL, NULL);
+ if (ret <= 0) {
+ dev_err(dev, "failed to parse _CRS method, error %d\n", ret);
+ return NULL;
+ }
+
+ list_for_each_entry(rentry, &list, node) {
+ if (resource_type(rentry->res) == IORESOURCE_MEM) {
+ res = *rentry->res;
+ break;
+ }
+ }
+
+ if (!rentry->res)
+ return NULL;
+
+ acpi_dev_free_resource_list(&list);
+ base = devm_ioremap_resource(dev, &res);
+ if (IS_ERR(base)) {
+ dev_err(dev, "PMU type %d: Fail to map resource\n", type);
+ return NULL;
+ }
+
+ uncore_dev = devm_kzalloc(dev, sizeof(*uncore_dev), GFP_KERNEL);
+ if (!uncore_dev)
+ return NULL;
+
+ uncore_dev->dev = dev;
+ uncore_dev->type = type;
+ uncore_dev->base = base;
+ uncore_dev->node = dev_to_node(dev);
+
+ raw_spin_lock_init(&uncore_dev->lock);
+
+ switch (uncore_dev->type) {
+ case PMU_TYPE_L3C:
+ uncore_dev->max_counters = UNCORE_MAX_COUNTERS;
+ uncore_dev->max_channels = UNCORE_L3_MAX_TILES;
+ uncore_dev->max_events = L3_EVENT_MAX;
+ uncore_dev->hrtimer_interval = UNCORE_HRTIMER_INTERVAL;
+ uncore_dev->attr_groups = l3c_pmu_attr_groups;
+ uncore_dev->name = devm_kasprintf(dev, GFP_KERNEL,
+ "uncore_l3c_%d", uncore_dev->node);
+ uncore_dev->init_cntr_base = init_cntr_base_l3c;
+ uncore_dev->start_event = uncore_start_event_l3c;
+ uncore_dev->stop_event = uncore_stop_event_l3c;
+ uncore_dev->select_channel = uncore_select_channel;
+ break;
+ case PMU_TYPE_DMC:
+ uncore_dev->max_counters = UNCORE_MAX_COUNTERS;
+ uncore_dev->max_channels = UNCORE_DMC_MAX_CHANNELS;
+ uncore_dev->max_events = DMC_EVENT_MAX;
+ uncore_dev->hrtimer_interval = UNCORE_HRTIMER_INTERVAL;
+ uncore_dev->attr_groups = dmc_pmu_attr_groups;
+ uncore_dev->name = devm_kasprintf(dev, GFP_KERNEL,
+ "uncore_dmc_%d", uncore_dev->node);
+ uncore_dev->init_cntr_base = init_cntr_base_dmc;
+ uncore_dev->start_event = uncore_start_event_dmc;
+ uncore_dev->stop_event = uncore_stop_event_dmc;
+ uncore_dev->select_channel = uncore_select_channel;
+ break;
+ case PMU_TYPE_INVALID:
+ devm_kfree(dev, uncore_dev);
+ uncore_dev = NULL;
+ break;
+ }
+
+ return uncore_dev;
+}
+
+static acpi_status thunderx2_pmu_uncore_dev_add(acpi_handle handle, u32 level,
+ void *data, void **return_value)
+{
+ struct thunderx2_pmu_uncore_dev *uncore_dev;
+ struct acpi_device *adev;
+ enum thunderx2_uncore_type type;
+ int channel;
+
+ if (acpi_bus_get_device(handle, &adev))
+ return AE_OK;
+ if (acpi_bus_get_status(adev) || !adev->status.present)
+ return AE_OK;
+
+ type = get_uncore_device_type(adev);
+ if (type == PMU_TYPE_INVALID)
+ return AE_OK;
+
+ uncore_dev = init_pmu_uncore_dev((struct device *)data, handle,
+ adev, type);
+
+ if (!uncore_dev)
+ return AE_ERROR;
+
+ for (channel = 0; channel < uncore_dev->max_channels; channel++) {
+ if (thunderx2_pmu_uncore_add(uncore_dev, channel)) {
+ /* Can't add the PMU device, abort */
+ return AE_ERROR;
+ }
+ }
+ return AE_OK;
+}
+
+static int thunderx2_uncore_pmu_offline_cpu(unsigned int cpu,
+ struct hlist_node *node)
+{
+ int new_cpu;
+ struct thunderx2_pmu_uncore_channel *pmu_uncore;
+
+ pmu_uncore = hlist_entry_safe(node,
+ struct thunderx2_pmu_uncore_channel, node);
+ if (cpu != pmu_uncore->cpu)
+ return 0;
+
+ new_cpu = cpumask_any_and(
+ cpumask_of_node(pmu_uncore->uncore_dev->node),
+ cpu_online_mask);
+ if (new_cpu >= nr_cpu_ids)
+ return 0;
+
+ pmu_uncore->cpu = new_cpu;
+ perf_pmu_migrate_context(&pmu_uncore->pmu, cpu, new_cpu);
+ return 0;
+}
+
+static const struct acpi_device_id thunderx2_uncore_acpi_match[] = {
+ {"CAV901C", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, thunderx2_uncore_acpi_match);
+
+static int thunderx2_uncore_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ acpi_handle handle;
+ acpi_status status;
+
+ set_dev_node(dev, acpi_get_node(ACPI_HANDLE(dev)));
+
+ /* Make sure firmware supports DMC/L3C set channel smc call */
+ if (test_uncore_select_channel_early(dev))
+ return -ENODEV;
+
+ if (!has_acpi_companion(dev))
+ return -ENODEV;
+
+ handle = ACPI_HANDLE(dev);
+ if (!handle)
+ return -EINVAL;
+
+ /* Walk through the tree for all PMU UNCORE devices */
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+ thunderx2_pmu_uncore_dev_add,
+ NULL, dev, NULL);
+ if (ACPI_FAILURE(status)) {
+ dev_err(dev, "failed to probe PMU devices\n");
+ return_ACPI_STATUS(status);
+ }
+
+ dev_info(dev, "node%d: pmu uncore registered\n", dev_to_node(dev));
+ return 0;
+}
+
+static struct platform_driver thunderx2_uncore_driver = {
+ .probe = thunderx2_uncore_probe,
+ .driver = {
+ .name = "thunderx2-uncore-pmu",
+ .acpi_match_table = ACPI_PTR(thunderx2_uncore_acpi_match),
+ },
+};
+
+static int __init register_thunderx2_uncore_driver(void)
+{
+ int ret;
+
+ ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_THUNDERX2_UNCORE_ONLINE,
+ "perf/tx2/uncore:online",
+ NULL,
+ thunderx2_uncore_pmu_offline_cpu);
+ if (ret)
+ return ret;
+
+ return platform_driver_register(&thunderx2_uncore_driver);
+
+}
+device_initcall(register_thunderx2_uncore_driver);
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 8796ba3..eb0c896 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -161,6 +161,7 @@ enum cpuhp_state {
CPUHP_AP_PERF_ARM_L2X0_ONLINE,
CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
+ CPUHP_AP_PERF_ARM_THUNDERX2_UNCORE_ONLINE,
CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE,
CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE,
CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,
--
2.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v9 3/7] cpuset: Add cpuset.sched.load_balance flag to v2
From: Waiman Long @ 2018-06-21 7:40 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Tejun Heo, Li Zefan, Johannes Weiner, Ingo Molnar, cgroups,
linux-kernel, linux-doc, kernel-team, pjt, luto, Mike Galbraith,
torvalds, Roman Gushchin, Juri Lelli, Patrick Bellasi,
Thomas Gleixner, Frederic Weisbecker
In-Reply-To: <20180620144613.GP2476@hirez.programming.kicks-ass.net>
On 06/20/2018 10:46 PM, Peter Zijlstra wrote:
> On Thu, May 31, 2018 at 12:42:20PM -0400, Waiman Long wrote:
>> Thinking about isolcpus emulation, I now realize that it is more than
>> just disabling load balancing. it also disables some kernel threads like
>> kworker from running so that an userspace application can monopolize as
>> much of a cpu as possible. Disabling kernel threads from running isn't
>> that hard if it is only done once at boot time. it is trickier if we
>> have to do it at run time.
> Don't think it is all that difficult, we just need a notifier for when
> that housekeeping thing changes and ensure that everybody who uses it
> re-evaluates crap.
Yes, it is certainly doable. I can work on that on my free time once the
first cpuset v2 patch is done. There is enough complexity in the current
patchset and I don't want to add stuff that is not a part of the core
cpuset functionality at this point. We can also add new feature in the
future, but once it is in, it is hard to change it.
>> Without good isolcpus emulation, disabling load balance kind of loses
>> its usefulness. So I am going to take out the load_balance flag for now
>> unless I hear objection otherwise.
> I'm not seeing the direct link between the load_balance flag and
> isolcpus emulation in the proposed stuff.
>
> We can tie the housekeeping mask to whatever CPUs remain in the root
> cgroup, couple that to that notifier and it should all just work I
> think.
The group of cpus in isolcpus are outside the reach of the scheduler and
so is equivalent to turning off load balancing in that sense. Of course,
there may also be other stuff that need to be considered in order to
have a proper emulation of isolcpus.
Cheers,
Longman
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v10 2/9] cpuset: Add new v2 cpuset.sched.domain_root flag
From: Waiman Long @ 2018-06-21 7:58 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Tejun Heo, Li Zefan, Johannes Weiner, Ingo Molnar, cgroups,
linux-kernel, linux-doc, kernel-team, pjt, luto, Mike Galbraith,
torvalds, Roman Gushchin, Juri Lelli, Patrick Bellasi
In-Reply-To: <20180620142735.GM2494@hirez.programming.kicks-ass.net>
On 06/20/2018 10:27 PM, Peter Zijlstra wrote:
> On Mon, Jun 18, 2018 at 12:14:01PM +0800, Waiman Long wrote:
>> + cpuset.sched.domain_root
> Why are we calling this a domain_root and not a partition?
A partition can consist of several cgroups in a tree structure. That
flag should only be set at the root of a partition. I will change the
name to partition_root if you think this name is acceptable.
>
>> + A read-write single value file which exists on non-root
>> + cpuset-enabled cgroups. It is a binary value flag that accepts
>> + either "0" (off) or "1" (on). This flag is set by the parent
>> + and is not delegatable.
> You still haven't answered:
> ,
> https://lkml.kernel.org/r/20180531094943.GG12180@hirez.programming.kicks-ass.net
>
> the question stands.
I am sorry to miss your question. Turning on domain_root will affects
the cpu mapping in the parent. That is why it cannot be set by the child
as a child is not supposed to be able to affect the parent.
As for the inconsistency between the real root and the container root,
this is true for almost all the controllers. So it is a generic problem.
One possible solution is to create a kind a pseudo root cgroup for the
container that looks and feels like a real root. But is there really a
need to do that?
Cheers,
Longman
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v10 2/9] cpuset: Add new v2 cpuset.sched.domain_root flag
From: Waiman Long @ 2018-06-21 8:05 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Tejun Heo, Li Zefan, Johannes Weiner, Ingo Molnar, cgroups,
linux-kernel, linux-doc, kernel-team, pjt, luto, Mike Galbraith,
torvalds, Roman Gushchin, Juri Lelli, Patrick Bellasi
In-Reply-To: <b44b0748-9fec-6bb0-7665-435487e5d8b3@redhat.com>
On 06/21/2018 03:58 PM, Waiman Long wrote:
> On 06/20/2018 10:27 PM, Peter Zijlstra wrote:
>> On Mon, Jun 18, 2018 at 12:14:01PM +0800, Waiman Long wrote:
>>> + cpuset.sched.domain_root
>> Why are we calling this a domain_root and not a partition?
> A partition can consist of several cgroups in a tree structure. That
> flag should only be set at the root of a partition. I will change the
> name to partition_root if you think this name is acceptable.
>
>>> + A read-write single value file which exists on non-root
>>> + cpuset-enabled cgroups. It is a binary value flag that accepts
>>> + either "0" (off) or "1" (on). This flag is set by the parent
>>> + and is not delegatable.
>> You still haven't answered:
>> ,
>> https://lkml.kernel.org/r/20180531094943.GG12180@hirez.programming.kicks-ass.net
>>
>> the question stands.
> I am sorry to miss your question. Turning on domain_root will affects
> the cpu mapping in the parent. That is why it cannot be set by the child
> as a child is not supposed to be able to affect the parent.
After thinking a bit more about it, you are right that I should not use
the term "not delegatable" here. I will rephrase in the next version.
Cheers,
Longman
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v10 6/9] cpuset: Make generate_sched_domains() recognize reserved_cpus
From: Waiman Long @ 2018-06-21 8:14 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Tejun Heo, Li Zefan, Johannes Weiner, Ingo Molnar, cgroups,
linux-kernel, linux-doc, kernel-team, pjt, luto, Mike Galbraith,
torvalds, Roman Gushchin, Juri Lelli, Patrick Bellasi
In-Reply-To: <20180620141730.GK2494@hirez.programming.kicks-ass.net>
On 06/20/2018 10:17 PM, Peter Zijlstra wrote:
> On Mon, Jun 18, 2018 at 12:14:06PM +0800, Waiman Long wrote:
>> The generate_sched_domains() function is modified to make it work
>> correctly with the newly introduced reserved_cpus mask for schedule
>> domains generation.
> Why isn't this (and the previous) patch part of the patch that
> introduces reserved_cpus? It seems weird to have this broken
> intermediate state.
I was trying to break the reserved cpu patch into smaller meaningful
pieces that will be easier to review. The individual patches can be
compiled cleanly one-by-one, though I didn't check if they are
functional if not all of them are applied.
Cheers,
Longman
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v10 3/9] cpuset: Simulate auto-off of sched.domain_root at cgroup removal
From: Waiman Long @ 2018-06-21 8:22 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Tejun Heo, Li Zefan, Johannes Weiner, Ingo Molnar, cgroups,
linux-kernel, linux-doc, kernel-team, pjt, luto, Mike Galbraith,
torvalds, Roman Gushchin, Juri Lelli, Patrick Bellasi
In-Reply-To: <20180620141144.GI2494@hirez.programming.kicks-ass.net>
On 06/20/2018 10:11 PM, Peter Zijlstra wrote:
> On Mon, Jun 18, 2018 at 12:14:02PM +0800, Waiman Long wrote:
>> @@ -1058,7 +1060,12 @@ static int update_reserved_cpumask(struct cpuset *cpuset,
>> * Check if any CPUs in addmask or delmask are in the effective_cpus
>> * of a sibling cpuset. The implied cpu_exclusive of a scheduling
>> * domain root will ensure there are no overlap in cpus_allowed.
>> + *
>> + * This check is skipped if the cpuset is dying.
> Comments that state what the code does are mostly useless; please
> explain _why_ if anything.
I am adding more restrictions on where the domain_root can be turned on
to make sure that there will be no surprise.
I have a script to test the new cpuset v2 functionality and found that
cgroup deletion may sometime failed if there was not enough time for the
previous operation to complete. That is the reason why I relax the
checking for dying cgroup to make my test script pass.
Cheers,
Longman
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 5/5] Documentation/ABI: Add details of PCI AER statistics
From: poza @ 2018-06-21 9:19 UTC (permalink / raw)
To: rajatxjain
Cc: Rajat Jain, Bjorn Helgaas, Jonathan Corbet, Philippe Ombredanne,
Kate Stewart, Thomas Gleixner, Greg Kroah-Hartman,
Frederick Lawler, Busch, Keith, Gabriele Paoloni,
Alexandru Gagniuc, Thomas Tai, Steven Rostedt, linux-pci,
linux-doc, Linux Kernel Mailing List, Jes Sorensen, Kyle McMartin
In-Reply-To: <CAA93t1r2fG+U9av2jj8jKrVfHrc_UABOS3DVO-UfHgcsJKyv7g@mail.gmail.com>
On 2018-06-19 22:01, Rajat Jain wrote:
> On Mon, Jun 18, 2018 at 11:03 PM, <poza@codeaurora.org> wrote:
>> On 2018-06-19 05:41, Rajat Jain wrote:
>>>
>>> Hello,
>>>
>>> On Sat, Jun 16, 2018 at 10:24 PM <poza@codeaurora.org> wrote:
>>>>
>>>>
>>>> On 2018-05-23 23:28, Rajat Jain wrote:
>>>> > Add the PCI AER statistics details to
>>>> > Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
>>>> > and provide a pointer to it in
>>>> > Documentation/PCI/pcieaer-howto.txt
>>>> >
>>>> > Signed-off-by: Rajat Jain <rajatja@google.com>
>>>> > ---
>>>> > v2: Move the documentation to Documentation/ABI/
>>>> >
>>>> > .../testing/sysfs-bus-pci-devices-aer_stats | 103 ++++++++++++++++++
>>>> > Documentation/PCI/pcieaer-howto.txt | 5 +
>>>> > 2 files changed, 108 insertions(+)
>>>> > create mode 100644
>>>> > Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
>>>> >
>>>> > diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
>>>> > b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
>>>> > new file mode 100644
>>>> > index 000000000000..f55c389290ac
>>>> > --- /dev/null
>>>> > +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
>>>> > @@ -0,0 +1,103 @@
>>>> > +==========================
>>>> > +PCIe Device AER statistics
>>>> > +==========================
>>>> > +These attributes show up under all the devices that are AER capable.
>>>> > These
>>>> > +statistical counters indicate the errors "as seen/reported by the
>>>> > device".
>>>> > +Note that this may mean that if an end point is causing problems, the
>>>> > AER
>>>> > +counters may increment at its link partner (e.g. root port) because
>>>> > the
>>>> > +errors will be "seen" / reported by the link partner and not the the
>>>> > +problematic end point itself (which may report all counters as 0 as it
>>>> > never
>>>> > +saw any problems).
>>>> > +
>>>> > +Where:
>>>> > /sys/bus/pci/devices/<dev>/aer_stats/dev_total_cor_errs
>>>> > +Date: May 2018
>>>> > +Kernel Version: 4.17.0
>>>> > +Contact: linux-pci@vger.kernel.org, rajatja@google.com
>>>> > +Description: Total number of correctable errors seen and reported by
>>>> > this
>>>> > + PCI device using ERR_COR.
>>>> > +
>>>> > +Where:
>>>> > /sys/bus/pci/devices/<dev>/aer_stats/dev_total_fatal_errs
>>>> > +Date: May 2018
>>>> > +Kernel Version: 4.17.0
>>>> > +Contact: linux-pci@vger.kernel.org, rajatja@google.com
>>>> > +Description: Total number of uncorrectable fatal errors seen and
>>>> > reported
>>>> > + by this PCI device using ERR_FATAL.
>>>> > +
>>>> > +Where:
>>>> > /sys/bus/pci/devices/<dev>/aer_stats/dev_total_nonfatal_errs
>>>> > +Date: May 2018
>>>> > +Kernel Version: 4.17.0
>>>> > +Contact: linux-pci@vger.kernel.org, rajatja@google.com
>>>> > +Description: Total number of uncorrectable non-fatal errors seen and
>>>> > reported
>>>> > + by this PCI device using ERR_NONFATAL.
>>>> > +
>>>> > +Where:
>>>> > /sys/bus/pci/devices/<dev>/aer_stats/dev_breakdown_correctable
>>>> > +Date: May 2018
>>>> > +Kernel Version: 4.17.0
>>>> > +Contact: linux-pci@vger.kernel.org, rajatja@google.com
>>>> > +Description: Breakdown of of correctable errors seen and reported by
>>>> > this
>>>> > + PCI device using ERR_COR. A sample result looks like
>>>> > this:
>>>> > +-----------------------------------------
>>>> > +Receiver Error = 0x174
>>>> > +Bad TLP = 0x19
>>>> > +Bad DLLP = 0x3
>>>> > +RELAY_NUM Rollover = 0x0
>>>> > +Replay Timer Timeout = 0x1
>>>> > +Advisory Non-Fatal = 0x0
>>>> > +Corrected Internal Error = 0x0
>>>> > +Header Log Overflow = 0x0
>>>> > +-----------------------------------------
>>>> why hex display ? decimal is easy to read as these are counters.
>>>
>>>
>>> Have no particular preference. Since these can be potentially large
>>> numbers, just had a random thought that hex might make it more
>>> concise. I can change to decimal if that is preferable.
>>>
>>>> > +
>>>> > +Where:
>>>> > /sys/bus/pci/devices/<dev>/aer_stats/dev_breakdown_uncorrectable
>>>> > +Date: May 2018
>>>> > +Kernel Version: 4.17.0
>>>> > +Contact: linux-pci@vger.kernel.org, rajatja@google.com
>>>> > +Description: Breakdown of of correctable errors seen and reported by
>>>> > this
>>>> > + PCI device using ERR_FATAL or ERR_NONFATAL. A sample
>>>> > result
>>>> > + looks like this:
>>>> > +-----------------------------------------
>>>> > +Undefined = 0x0
>>>> > +Data Link Protocol = 0x0
>>>> > +Surprise Down Error = 0x0
>>>> > +Poisoned TLP = 0x0
>>>> > +Flow Control Protocol = 0x0
>>>> > +Completion Timeout = 0x0
>>>> > +Completer Abort = 0x0
>>>> > +Unexpected Completion = 0x0
>>>> > +Receiver Overflow = 0x0
>>>> > +Malformed TLP = 0x0
>>>> > +ECRC = 0x0
>>>> > +Unsupported Request = 0x0
>>>> > +ACS Violation = 0x0
>>>> > +Uncorrectable Internal Error = 0x0
>>>> > +MC Blocked TLP = 0x0
>>>> > +AtomicOp Egress Blocked = 0x0
>>>> > +TLP Prefix Blocked Error = 0x0
>>>> > +-----------------------------------------
>>>> > +
>>>> > +============================
>>>> > +PCIe Rootport AER statistics
>>>> > +============================
>>>> > +These attributes showup under only the rootports that are AER capable.
>>>> > These
>>>> > +indicate the number of error messages as "reported to" the rootport.
>>>> > Please note
>>>> > +that the rootports also transmit (internally) the ERR_* messages for
>>>> > errors seen
>>>> > +by the internal rootport PCI device, so these counters includes them
>>>> > and are
>>>> > +thus cumulative of all the error messages on the PCI hierarchy
>>>> > originating
>>>> > +at that root port.
>>>>
>>>> what about switches and bridges ?
>>>
>>>
>>> What about them? AIUI, the switches forward the ERR_ messages from
>>> downstream devices to the rootport, like they do with standard
>>> messages. They can potentially generate their own ERR_ message and
>>> that would be reported no different than other end point devices.
>>
>>
>>
>> yes, what I meant to ask is; the ERR_FATAL msg coming from EP, can be
>> contained by switch
>> and the error handling code thinks that, the error is contained by
>> switch
>> irrespective of
>> AER or DPC, and it will think that the problem could be with
>> Switch/bridge
>> upstream link.
>>
>> hence the pci_dev of the switch where you should be increment your
>> counters.
>> of course ER_FATAL would have traversed till RP, but that doesnt meant
>> that
>> you account the error there.
>
> In this case, for the pci_dev for the rootport:
> - rootport_total_fatal_errors will be incremented (since it will get
> ERR_FATAL)
> - dev_total_fatal_errors will not be incremented.
ok but my confusion is: should you not be incrementing counter against
pci_dev of switch ? and not the RP ?
because the problem was with upstream link of the EP (e.g. switch)
>
> The dev_total_fatal_errors will be incremented only for the pci device
> identified by the "Error Source Identification Register" in the PCIe
> spec. Does this help clarify?
>
>>
>>
>>>
>>>> Also Can you give some idea as e.g what is the difference between
>>>> dev_total_fatal_errs and rootport_total_fatal_errs (assuming that
>>>> both
>>>> are same pci_dev.
>>>
>>>
>>> For a pci_dev representing the rootport:
>>>
>>> dev_total_fatal_errors = how many times this PCI device *experienced*
>>> a fatal problem on its own (i.e. either link issues while talking to
>>> its link partner, or some internal errors).
>>>
>>> rootport_total_fatal_errors = how many times this rootport was
>>> *informed* about a problem (via ERR_* messages) in the PCI hierarchy
>>> that originates at it (can be any link further downstream). This
>>> includes the dev_total_fatal_errors also, because any errors detected
>>> by the rootport are also "informed" to itself via ERR_* messages. In
>>> reality, this is just the total number of ERR_FATAL messages received
>>> at the rootport. This sysfs attribute will only exist for root ports.
>>>
>>>>
>>>> rootport_total_fatal_errs gives me an idea that how many times
>>>> things
>>>> have been failed under this pci_dev ?
>>>
>>>
>>> Yes, as above.
>>>
>>>> which means num of downstream link problems. but I am still trying
>>>> to
>>>> make sense as how it could be used,
>>>> since we dont have BDF information associated with the number of
>>>> errors
>>>> anywhere (except these AER print messages)
>>>>
>>>
>>> Agree. That is a limitation. The challenges being more record
>>> keeping,
>>> more complicated sysfs representation, and given that PCI devices may
>>> come and go, how do we know it is the same device before we collate
>>> their stats etc.
>>>
>>>>
>>>> and dev_total_fatal_errs as you mentioned above that problematic EP,
>>>> then say root-port will report it and increment
>>>> dev_total_fatal_errs ++
>>>> does it also increment root-port_total_fatal_errs ++ in above
>>>> scenario ?
>>>
>>>
>>> Yes, as above, it will also root-port_total_fatal_errs++ for the root
>>> port of that hierarchy.
>>>
>>> Thanks,
>>>
>>> Rajat
>>>
>>>>
>>>> > +
>>>> > +Where:
>>>> > /sys/bus/pci/devices/<dev>/aer_stats/rootport_total_cor_errs
>>>> > +Date: May 2018
>>>> > +Kernel Version: 4.17.0
>>>> > +Contact: linux-pci@vger.kernel.org, rajatja@google.com
>>>> > +Description: Total number of ERR_COR messages reported to rootport.
>>>> > +
>>>> > +Where:
>>>> > /sys/bus/pci/devices/<dev>/aer_stats/rootport_total_fatal_errs
>>>> > +Date: May 2018
>>>> > +Kernel Version: 4.17.0
>>>> > +Contact: linux-pci@vger.kernel.org, rajatja@google.com
>>>> > +Description: Total number of ERR_FATAL messages reported to rootport.
>>>> > +
>>>> > +Where:
>>>> > /sys/bus/pci/devices/<dev>/aer_stats/rootport_total_nonfatal_errs
>>>> > +Date: May 2018
>>>> > +Kernel Version: 4.17.0
>>>> > +Contact: linux-pci@vger.kernel.org, rajatja@google.com
>>>> > +Description: Total number of ERR_NONFATAL messages reported to
>>>> > rootport.
>>>> > diff --git a/Documentation/PCI/pcieaer-howto.txt
>>>> > b/Documentation/PCI/pcieaer-howto.txt
>>>> > index acd0dddd6bb8..91b6e677cb8c 100644
>>>> > --- a/Documentation/PCI/pcieaer-howto.txt
>>>> > +++ b/Documentation/PCI/pcieaer-howto.txt
>>>> > @@ -73,6 +73,11 @@ In the example, 'Requester ID' means the ID of the
>>>> > device who sends
>>>> > the error message to root port. Pls. refer to pci express specs for
>>>> > other fields.
>>>> >
>>>> > +2.4 AER Statistics / Counters
>>>> > +
>>>> > +When PCIe AER errors are captured, the counters / statistics are also
>>>> > exposed
>>>> > +in form of sysfs attributes which are documented at
>>>> > +Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
>>>> >
>>>> > 3. Developer Guide
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v10 2/9] cpuset: Add new v2 cpuset.sched.domain_root flag
From: Peter Zijlstra @ 2018-06-21 9:20 UTC (permalink / raw)
To: Waiman Long
Cc: Tejun Heo, Li Zefan, Johannes Weiner, Ingo Molnar, cgroups,
linux-kernel, linux-doc, kernel-team, pjt, luto, Mike Galbraith,
torvalds, Roman Gushchin, Juri Lelli, Patrick Bellasi
In-Reply-To: <b44b0748-9fec-6bb0-7665-435487e5d8b3@redhat.com>
On Thu, Jun 21, 2018 at 03:58:06PM +0800, Waiman Long wrote:
> As for the inconsistency between the real root and the container root,
> this is true for almost all the controllers. So it is a generic problem.
> One possible solution is to create a kind a pseudo root cgroup for the
> container that looks and feels like a real root. But is there really a
> need to do that?
I don't really know. I thought the idea was to make containers
indistinguishable from a real system. Now I know we're really rather far
away from that in reality, and I really have no clue how important all
that is.
It all depends on how exactly this works; is it like I assumed, that
this file is owned by the parent instead of the current directory? And
that if you namespace this, you have an effective read-only file?
Then fixing the inconsistency is trivial; simply provide a read-only
file for the actual root cgroup too.
And if the solution is trivial, I don't see a good reason not to do it.
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v10 2/9] cpuset: Add new v2 cpuset.sched.domain_root flag
From: Peter Zijlstra @ 2018-06-21 9:27 UTC (permalink / raw)
To: Waiman Long
Cc: Tejun Heo, Li Zefan, Johannes Weiner, Ingo Molnar, cgroups,
linux-kernel, linux-doc, kernel-team, pjt, luto, Mike Galbraith,
torvalds, Roman Gushchin, Juri Lelli, Patrick Bellasi
In-Reply-To: <b44b0748-9fec-6bb0-7665-435487e5d8b3@redhat.com>
On Thu, Jun 21, 2018 at 03:58:06PM +0800, Waiman Long wrote:
> On 06/20/2018 10:27 PM, Peter Zijlstra wrote:
> > On Mon, Jun 18, 2018 at 12:14:01PM +0800, Waiman Long wrote:
> >> + cpuset.sched.domain_root
> > Why are we calling this a domain_root and not a partition?
>
> A partition can consist of several cgroups in a tree structure. That
> flag should only be set at the root of a partition. I will change the
> name to partition_root if you think this name is acceptable.
The flag indicates the 'effective_cpus' things of the current group is a
partition. The fact that it can have sub-partitions doesn't really
matter does it.
Just call it 'partition', leave out the whole root stuff, all of cgroup
is hierarchical and you can have sub-groups we don't go around calling
everything a root.
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v5 09/11] pci_endpoint_test: Add 2 ioctl commands
From: Gustavo Pimentel @ 2018-06-21 10:23 UTC (permalink / raw)
To: Randy Dunlap, Gustavo Pimentel, bhelgaas@google.com,
lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com,
jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com,
jesper.nilsson@axis.com, sboyd@codeaurora.org
Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <dd75ced1-e4c3-8c94-3bab-200e2ecdd8b8@infradead.org>
On 20/06/2018 19:12, Randy Dunlap wrote:
> On 06/20/2018 09:28 AM, Gustavo Pimentel wrote:
>> Add MSI-X support and update driver documentation accordingly.
>>
>> Add 2 new IOCTL commands:
>> - Allow to reconfigure driver IRQ type in runtime.
>> - Allow to retrieve current driver IRQ type configured.
>>
>> Signed-off-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
>> ---
>> Change v2->v3: | --------------------------------------------------------------------------------------------
>> - New patch file created base on the previous patch | --------------------------------------------------------------------------------------------
>> "misc: pci_endpoint_test: Add MSI-X support" patch file following | --------------------------------------------------------------------------------------------
>> Kishon's suggestion. | --------------------------------------------------------------------------------------------
>> Change v3->v4: | --------------------------------------------------------------------------------------------
>> - Rebased to Lorenzo's master branch v4.18-rc1.
>> Change v4->v5:
>> - Nothing changed, just to follow the patch set version.
>>
>> Documentation/misc-devices/pci-endpoint-test.txt | 3 +
>> drivers/misc/pci_endpoint_test.c | 177 +++++++++++++++++------
>> 2 files changed, 132 insertions(+), 48 deletions(-)
>>
>> diff --git a/Documentation/misc-devices/pci-endpoint-test.txt b/Documentation/misc-devices/pci-endpoint-test.txt
>> index fdfa0f6..58ccca4 100644
>> --- a/Documentation/misc-devices/pci-endpoint-test.txt
>> +++ b/Documentation/misc-devices/pci-endpoint-test.txt
>> @@ -28,6 +28,9 @@ ioctl
>> to be tested should be passed as argument.
>> PCITEST_MSIX: Tests message signalled interrupts. The MSI-X number
>> to be tested should be passed as argument.
>> + PCITEST_SET_IRQTYPE: Changes driver IRQ type configuration. The IRQ type
>> + should be passed as argument (0: Legacy, 1:MSI, 2:MSI-X).
>> + PCITEST_GET_IRQTYPE: Gets driver IRQ type configuration.
>> PCITEST_WRITE: Perform write tests. The size of the buffer should be passed
>> as argument.
>> PCITEST_READ: Perform read tests. The size of the buffer should be passed
>> diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
>> index 2b58887..82fa0c2 100644
>> --- a/drivers/misc/pci_endpoint_test.c
>> +++ b/drivers/misc/pci_endpoint_test.c
>
> Hi,
>
> The ioctl "type" (as "type" is used in <uapi/asm-generic/ioctl.h>),
> value of 'P' in this case, should be documented in
> Documentation/ioctl/ioctl-number.txt.
Hi Randy,
I wasn't aware of this file. Adding the entry bellow would be suitable?
'P' 01-09 drivers/misc/pci_endpoint_test.c conflict!
Regards,
Gustavo
>
> thanks,
>
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox